From 7f4cf4f4f3e9743b52a89fd3cf8fe4aa9768658c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 11 Jul 2024 00:35:36 +0200 Subject: [PATCH 01/53] introduce DynResource & DynBuffer as first user --- wgpu-hal/src/dx12/mod.rs | 21 ++++++++++ wgpu-hal/src/dynamic/mod.rs | 83 +++++++++++++++++++++++++++++++++++++ wgpu-hal/src/empty.rs | 4 ++ wgpu-hal/src/gles/mod.rs | 20 +++++++++ wgpu-hal/src/lib.rs | 7 +++- wgpu-hal/src/metal/mod.rs | 20 +++++++++ wgpu-hal/src/vulkan/mod.rs | 21 ++++++++++ 7 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 wgpu-hal/src/dynamic/mod.rs diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 8d08b8f72d..165a970efd 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -87,6 +87,25 @@ impl crate::Api for Api { type AccelerationStructure = AccelerationStructure; } +crate::impl_dyn_resource!( + BindGroup, + BindGroupLayout, + Buffer, + CommandBuffer, + CommandEncoder, + ComputePipeline, + Fence, + PipelineCache, + PipelineLayout, + QuerySet, + RenderPipeline, + Sampler, + ShaderModule, + Surface, + Texture, + TextureView +); + // Limited by D3D12's root signature size of 64. Each element takes 1 or 2 entries. const MAX_ROOT_ELEMENTS: usize = 64; const ZERO_BUFFER_SIZE: wgt::BufferAddress = 256 << 10; @@ -407,6 +426,8 @@ pub struct Buffer { unsafe impl Send for Buffer {} unsafe impl Sync for Buffer {} +impl crate::DynBuffer for Buffer {} + impl crate::BufferBinding<'_, Api> { fn resolve_size(&self) -> wgt::BufferAddress { match self.size { diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs new file mode 100644 index 0000000000..9b0ffe6d1c --- /dev/null +++ b/wgpu-hal/src/dynamic/mod.rs @@ -0,0 +1,83 @@ +use std::any::Any; + +use wgt::WasmNotSendSync; + +/// Base trait for all resources, allows downcasting via [`Any`]. +pub trait DynResource: Any + WasmNotSendSync + 'static { + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; +} + +/// Utility macro for implementing `DynResource` for a list of types. +macro_rules! impl_dyn_resource { + ($($type:ty),*) => { + $( + impl crate::DynResource for $type { + fn as_any(&self) -> &dyn ::std::any::Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any { + self + } + } + )* + }; +} +pub(crate) use impl_dyn_resource; + +/// Extension trait for `DynResource` used by implementations of various dynamic resource traits. +trait DynResourceExt { + /// # Panics + /// + /// - Panics if `self` is not downcastable to `T`. + fn expect_downcast_ref(&self) -> &T; + /// # Panics + /// + /// - Panics if `self` is not downcastable to `T`. + fn expect_downcast_mut(&mut self) -> &mut T; + + /// Unboxes a `Box` to a concrete type. + /// + /// # Safety + /// + /// - `self` must be the correct concrete type. + unsafe fn unbox(self: Box) -> T; +} + +impl DynResourceExt for R { + fn expect_downcast_ref<'a, T: DynResource>(&'a self) -> &'a T { + self.as_any() + .downcast_ref() + .expect("Resource doesn't have the expected backend type.") + } + + fn expect_downcast_mut<'a, T: DynResource>(&'a mut self) -> &'a mut T { + self.as_any_mut() + .downcast_mut() + .expect("Resource doesn't have the expected backend type.") + } + + unsafe fn unbox(self: Box) -> T { + debug_assert!( + ::type_id(self.as_ref()) == std::any::TypeId::of::(), + "Resource doesn't have the expected type, expected {:?}, got {:?}", + std::any::TypeId::of::(), + ::type_id(self.as_ref()) + ); + + let casted_ptr = Box::into_raw(self).cast::(); + // SAFETY: This is adheres to the safety contract of `Box::from_raw` because: + // + // - We are casting the value of a previously `Box`ed value, which guarantees: + // - `casted_ptr` is not null. + // - `casted_ptr` is valid for reads and writes, though by itself this does not mean + // valid reads and writes for `T` (read on for that). + // - We don't change the allocator. + // - The contract of `Box::from_raw` requires that an initialized and aligned `T` is stored + // within `casted_ptr`. + *unsafe { Box::from_raw(casted_ptr) } + } +} + +pub trait DynBuffer: DynResource + std::fmt::Debug {} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 956b7b08a5..4cee4501ea 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -40,6 +40,10 @@ impl crate::Api for Api { type ComputePipeline = Resource; } +crate::impl_dyn_resource!(Context, Encoder, Resource); + +impl crate::DynBuffer for Resource {} + impl crate::Instance for Context { type A = Api; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 459600df7e..bf04c3a63c 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -164,6 +164,24 @@ impl crate::Api for Api { type ComputePipeline = ComputePipeline; } +crate::impl_dyn_resource!( + BindGroup, + BindGroupLayout, + Buffer, + CommandBuffer, + CommandEncoder, + ComputePipeline, + Fence, + PipelineLayout, + QuerySet, + RenderPipeline, + Sampler, + ShaderModule, + Surface, + Texture, + TextureView +); + bitflags::bitflags! { /// Flags that affect internal code paths but do not /// change the exposed feature set. @@ -307,6 +325,8 @@ unsafe impl Sync for Buffer {} #[cfg(send_sync)] unsafe impl Send for Buffer {} +impl crate::DynBuffer for Buffer {} + #[derive(Clone, Debug)] pub enum TextureInner { Renderbuffer { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index bd60b029e0..89053b2a74 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -262,6 +262,11 @@ pub mod api { pub use super::vulkan::Api as Vulkan; } +mod dynamic; + +pub use dynamic::DynBuffer; +pub(crate) use dynamic::{impl_dyn_resource, DynResource}; + use std::{ borrow::{Borrow, Cow}, fmt, @@ -399,7 +404,7 @@ pub trait Api: Clone + fmt::Debug + Sized { /// [`CommandEncoder`]: Api::CommandEncoder type CommandBuffer: WasmNotSendSync + fmt::Debug; - type Buffer: fmt::Debug + WasmNotSendSync + 'static; + type Buffer: DynBuffer; type Texture: fmt::Debug + WasmNotSendSync + 'static; type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow; type TextureView: fmt::Debug + WasmNotSendSync; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 0003983706..c57137d73a 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -71,6 +71,24 @@ impl crate::Api for Api { type AccelerationStructure = AccelerationStructure; } +crate::impl_dyn_resource!( + BindGroup, + BindGroupLayout, + Buffer, + CommandBuffer, + CommandEncoder, + ComputePipeline, + Fence, + PipelineLayout, + QuerySet, + RenderPipeline, + Sampler, + ShaderModule, + Surface, + Texture, + TextureView +); + pub struct Instance { managed_metal_layer_delegate: surface::HalManagedMetalLayerDelegate, } @@ -460,6 +478,8 @@ pub struct Buffer { unsafe impl Send for Buffer {} unsafe impl Sync for Buffer {} +impl crate::DynBuffer for Buffer {} + impl Buffer { fn as_raw(&self) -> BufferPtr { unsafe { NonNull::new_unchecked(self.raw.as_ptr()) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index d4be64548a..f329551771 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -78,6 +78,25 @@ impl crate::Api for Api { type ComputePipeline = ComputePipeline; } +crate::impl_dyn_resource!( + BindGroup, + BindGroupLayout, + Buffer, + CommandBuffer, + CommandEncoder, + ComputePipeline, + Fence, + PipelineCache, + PipelineLayout, + QuerySet, + RenderPipeline, + Sampler, + ShaderModule, + Surface, + Texture, + TextureView +); + struct DebugUtils { extension: ext::debug_utils::Instance, messenger: vk::DebugUtilsMessengerEXT, @@ -631,6 +650,8 @@ pub struct Buffer { block: Option>>, } +impl crate::DynBuffer for Buffer {} + #[derive(Debug)] pub struct AccelerationStructure { raw: vk::AccelerationStructureKHR, From eddab98d6efbc5418deb3bd691dd3afc2be9b1a4 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 14 Jul 2024 23:05:38 +0200 Subject: [PATCH 02/53] Buffer bindings no longer depend on hal api struct, but directly on buffer type --- wgpu-core/src/device/resource.rs | 2 +- wgpu-hal/src/dx12/command.rs | 4 ++-- wgpu-hal/src/dx12/mod.rs | 2 +- wgpu-hal/src/empty.rs | 8 ++++++-- wgpu-hal/src/gles/command.rs | 4 ++-- wgpu-hal/src/lib.rs | 16 ++++++++++------ wgpu-hal/src/metal/command.rs | 4 ++-- wgpu-hal/src/metal/mod.rs | 2 +- wgpu-hal/src/vulkan/command.rs | 4 ++-- 9 files changed, 27 insertions(+), 19 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 927358ea2c..de21f0a39a 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1889,7 +1889,7 @@ impl Device { used: &mut BindGroupStates, limits: &wgt::Limits, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> { use crate::binding_model::CreateBindGroupError as Error; let (binding_ty, dynamic, min_size) = match decl.ty { diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 5e05a3bcf5..ad7c70e285 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -970,7 +970,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_index_buffer<'a>( &mut self, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, format: wgt::IndexFormat, ) { self.list.as_ref().unwrap().set_index_buffer( @@ -982,7 +982,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_vertex_buffer<'a>( &mut self, index: u32, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, ) { let vb = &mut self.pass.vertex_buffers[index as usize]; vb.BufferLocation = binding.resolve_address(); diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 165a970efd..d3a9bd0c65 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -428,7 +428,7 @@ unsafe impl Sync for Buffer {} impl crate::DynBuffer for Buffer {} -impl crate::BufferBinding<'_, Api> { +impl crate::BufferBinding<'_, Buffer> { fn resolve_size(&self) -> wgt::BufferAddress { match self.size { Some(size) => size.get(), diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 4cee4501ea..65cc488b46 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -391,11 +391,15 @@ impl crate::CommandEncoder for Encoder { unsafe fn set_index_buffer<'a>( &mut self, - binding: crate::BufferBinding<'a, Api>, + binding: crate::BufferBinding<'a, Resource>, format: wgt::IndexFormat, ) { } - unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: crate::BufferBinding<'a, Api>) { + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: crate::BufferBinding<'a, Resource>, + ) { } unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: Range) {} unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) {} diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index 2fcbc7cffe..daad78e52b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -978,7 +978,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_index_buffer<'a>( &mut self, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, format: wgt::IndexFormat, ) { self.state.index_offset = binding.offset; @@ -990,7 +990,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_vertex_buffer<'a>( &mut self, index: u32, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, ) { self.state.dirty_vbuf_mask |= 1 << index; let (_, ref mut vb) = self.state.vertex_buffers[index as usize]; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 89053b2a74..d8c658c071 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1235,10 +1235,14 @@ pub trait CommandEncoder: WasmNotSendSync + fmt::Debug { unsafe fn set_index_buffer<'a>( &mut self, - binding: BufferBinding<'a, Self::A>, + binding: BufferBinding<'a, ::Buffer>, format: wgt::IndexFormat, ); - unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: BufferBinding<'a, Self::A>); + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: BufferBinding<'a, ::Buffer>, + ); unsafe fn set_viewport(&mut self, rect: &Rect, depth_range: Range); unsafe fn set_scissor_rect(&mut self, rect: &Rect); unsafe fn set_stencil_reference(&mut self, value: u32); @@ -1736,9 +1740,9 @@ pub struct PipelineLayoutDescriptor<'a, A: Api> { } #[derive(Debug)] -pub struct BufferBinding<'a, A: Api> { +pub struct BufferBinding<'a, B: DynBuffer + ?Sized> { /// The buffer being bound. - pub buffer: &'a A::Buffer, + pub buffer: &'a B, /// The offset at which the bound region starts. /// @@ -1762,7 +1766,7 @@ pub struct BufferBinding<'a, A: Api> { } // Rust gets confused about the impl requirements for `A` -impl Clone for BufferBinding<'_, A> { +impl Clone for BufferBinding<'_, B> { fn clone(&self) -> Self { Self { buffer: self.buffer, @@ -1808,7 +1812,7 @@ pub struct BindGroupEntry { pub struct BindGroupDescriptor<'a, A: Api> { pub label: Label<'a>, pub layout: &'a A::BindGroupLayout, - pub buffers: &'a [BufferBinding<'a, A>], + pub buffers: &'a [BufferBinding<'a, A::Buffer>], pub samplers: &'a [&'a A::Sampler], pub textures: &'a [TextureBinding<'a, A>], pub entries: &'a [BindGroupEntry], diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index fafe3478fd..5aeb8fa524 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -915,7 +915,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_index_buffer<'a>( &mut self, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, format: wgt::IndexFormat, ) { let (stride, raw_type) = match format { @@ -933,7 +933,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_vertex_buffer<'a>( &mut self, index: u32, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, ) { let buffer_index = self.shared.private_caps.max_vertex_buffers as u64 - 1 - index as u64; let encoder = self.state.render.as_ref().unwrap(); diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index c57137d73a..a7937731d2 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -486,7 +486,7 @@ impl Buffer { } } -impl crate::BufferBinding<'_, Api> { +impl crate::BufferBinding<'_, Buffer> { fn resolve_size(&self) -> wgt::BufferAddress { match self.size { Some(size) => size.get(), diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 4f36e6f86c..2f24efeace 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -870,7 +870,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_index_buffer<'a>( &mut self, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, format: wgt::IndexFormat, ) { unsafe { @@ -885,7 +885,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn set_vertex_buffer<'a>( &mut self, index: u32, - binding: crate::BufferBinding<'a, super::Api>, + binding: crate::BufferBinding<'a, super::Buffer>, ) { let vk_buffers = [binding.buffer.raw]; let vk_offsets = [binding.offset]; From f9d47ec17ddb52f929833d84e454db1c8011f72e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 14 Jul 2024 23:18:18 +0200 Subject: [PATCH 03/53] BufferBarrier no longer depend on hal api struct, but directly on buffer type --- wgpu-core/src/track/buffer.rs | 4 ++-- wgpu-core/src/track/mod.rs | 2 +- wgpu-hal/src/dx12/command.rs | 2 +- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/command.rs | 2 +- wgpu-hal/src/lib.rs | 6 +++--- wgpu-hal/src/metal/command.rs | 2 +- wgpu-hal/src/vulkan/command.rs | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 8fdcf31674..0f2bc8cef9 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -284,7 +284,7 @@ impl BufferTracker { pub fn drain_transitions<'a, 'b: 'a>( &'b mut self, snatch_guard: &'a SnatchGuard<'a>, - ) -> impl Iterator> { + ) -> impl Iterator> { let buffer_barriers = self.temp.drain(..).map(|pending| { let buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) }; pending.into_hal(buf, snatch_guard) @@ -557,7 +557,7 @@ impl DeviceBufferTracker { &'a mut self, tracker: &'a BufferTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index bb0d8cee78..5f7a868251 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -261,7 +261,7 @@ impl PendingTransition { self, buf: &'a resource::Buffer, snatch_guard: &'a SnatchGuard<'a>, - ) -> hal::BufferBarrier<'a, A> { + ) -> hal::BufferBarrier<'a, A::Buffer> { let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed"); hal::BufferBarrier { buffer, diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index ad7c70e285..c5978e55e4 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -310,7 +310,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { self.temp.barriers.clear(); diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 65cc488b46..c4e2af8567 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -301,7 +301,7 @@ impl crate::CommandEncoder for Encoder { unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index daad78e52b..e7e3714038 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -273,7 +273,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { if !self .private_caps diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index d8c658c071..a3a21f7bf9 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1103,7 +1103,7 @@ pub trait CommandEncoder: WasmNotSendSync + fmt::Debug { unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) where - T: Iterator>; + T: Iterator::Buffer>>; unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where @@ -1975,8 +1975,8 @@ pub struct Rect { } #[derive(Debug, Clone)] -pub struct BufferBarrier<'a, A: Api> { - pub buffer: &'a A::Buffer, +pub struct BufferBarrier<'a, B: DynBuffer + ?Sized> { + pub buffer: &'a B, pub usage: Range, } diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 5aeb8fa524..db19727a5f 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -241,7 +241,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_buffers<'a, T>(&mut self, _barriers: T) where - T: Iterator>, + T: Iterator>, { } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 2f24efeace..ddce6c24ed 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -116,7 +116,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { //Note: this is done so that we never end up with empty stage flags let mut src_stages = vk::PipelineStageFlags::TOP_OF_PIPE; From 880e5a9ceb7b20adb837bf2debe5e04438ac60ba Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 14 Jul 2024 23:13:55 +0200 Subject: [PATCH 04/53] Introduce DynCommandEncoder, implement index & vertex buffer ops on it --- wgpu-hal/src/dynamic/command.rs | 37 +++++++++++++++++++++++++++++++++ wgpu-hal/src/dynamic/mod.rs | 16 ++++++++++++++ wgpu-hal/src/lib.rs | 4 ++-- 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 wgpu-hal/src/dynamic/command.rs diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs new file mode 100644 index 0000000000..899bd805a6 --- /dev/null +++ b/wgpu-hal/src/dynamic/command.rs @@ -0,0 +1,37 @@ +use crate::{BufferBinding, CommandEncoder}; + +use super::DynBuffer; + +pub trait DynCommandEncoder { + unsafe fn set_index_buffer<'a>( + &mut self, + binding: BufferBinding<'a, dyn DynBuffer>, + format: wgt::IndexFormat, + ); + + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: BufferBinding<'a, dyn DynBuffer>, + ); +} + +impl DynCommandEncoder for C { + unsafe fn set_index_buffer<'a>( + &mut self, + binding: BufferBinding<'a, dyn DynBuffer>, + format: wgt::IndexFormat, + ) { + let binding = binding.expect_downcast(); + unsafe { self.set_index_buffer(binding, format) }; + } + + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: BufferBinding<'a, dyn DynBuffer>, + ) { + let binding = binding.expect_downcast(); + unsafe { self.set_vertex_buffer(index, binding) }; + } +} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 9b0ffe6d1c..f93cc82a9a 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -1,7 +1,13 @@ +mod command; + +pub use self::command::DynCommandEncoder; + use std::any::Any; use wgt::WasmNotSendSync; +use crate::BufferBinding; + /// Base trait for all resources, allows downcasting via [`Any`]. pub trait DynResource: Any + WasmNotSendSync + 'static { fn as_any(&self) -> &dyn Any; @@ -81,3 +87,13 @@ impl DynResourceExt for R { } pub trait DynBuffer: DynResource + std::fmt::Debug {} + +impl<'a> BufferBinding<'a, dyn DynBuffer> { + pub fn expect_downcast(self) -> BufferBinding<'a, B> { + BufferBinding { + buffer: self.buffer.expect_downcast_ref(), + offset: self.offset, + size: self.size, + } + } +} diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index a3a21f7bf9..ba943c5f8b 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -264,8 +264,8 @@ pub mod api { mod dynamic; -pub use dynamic::DynBuffer; pub(crate) use dynamic::{impl_dyn_resource, DynResource}; +pub use dynamic::{DynBuffer, DynCommandEncoder}; use std::{ borrow::{Borrow, Cow}, @@ -392,7 +392,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type Device: Device; type Queue: Queue; - type CommandEncoder: CommandEncoder; + type CommandEncoder: DynCommandEncoder + CommandEncoder; /// This API's command buffer type. /// From 6f8ef5c55280411f978d7388129f3323303af001 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 15 Jul 2024 20:05:31 +0200 Subject: [PATCH 05/53] DynCommandEncoder implement begin/end encoding, debug markers, various buffer operations --- wgpu-hal/src/dynamic/command.rs | 79 +++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index 899bd805a6..fbeedd1753 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,8 +1,29 @@ -use crate::{BufferBinding, CommandEncoder}; +use crate::{ + BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, Label, MemoryRange, +}; -use super::DynBuffer; +use super::{DynBuffer, DynResourceExt as _}; + +pub trait DynCommandEncoder: std::fmt::Debug { + unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>; + + unsafe fn discard_encoding(&mut self); + + unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]); + + unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange); + + unsafe fn copy_buffer_to_buffer( + &mut self, + src: &dyn DynBuffer, + dst: &dyn DynBuffer, + regions: &[BufferCopy], + ); + + unsafe fn insert_debug_marker(&mut self, label: &str); + unsafe fn begin_debug_marker(&mut self, group_label: &str); + unsafe fn end_debug_marker(&mut self); -pub trait DynCommandEncoder { unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, @@ -17,6 +38,58 @@ pub trait DynCommandEncoder { } impl DynCommandEncoder for C { + unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError> { + unsafe { C::begin_encoding(self, label) } + } + + unsafe fn discard_encoding(&mut self) { + unsafe { C::discard_encoding(self) } + } + + unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]) { + let barriers = barriers.iter().map(|barrier| BufferBarrier { + buffer: barrier.buffer.expect_downcast_ref(), + usage: barrier.usage.clone(), + }); + unsafe { self.transition_buffers(barriers) }; + } + + unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange) { + let buffer = buffer.expect_downcast_ref(); + unsafe { C::clear_buffer(self, buffer, range) }; + } + + unsafe fn copy_buffer_to_buffer( + &mut self, + src: &dyn DynBuffer, + dst: &dyn DynBuffer, + regions: &[BufferCopy], + ) { + let src = src.expect_downcast_ref(); + let dst = dst.expect_downcast_ref(); + unsafe { + C::copy_buffer_to_buffer(self, src, dst, regions.iter().copied()); + } + } + + unsafe fn insert_debug_marker(&mut self, label: &str) { + unsafe { + C::insert_debug_marker(self, label); + } + } + + unsafe fn begin_debug_marker(&mut self, group_label: &str) { + unsafe { + C::begin_debug_marker(self, group_label); + } + } + + unsafe fn end_debug_marker(&mut self) { + unsafe { + C::end_debug_marker(self); + } + } + unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, From debe0414f17dd64663c174c573179c45d1400f03 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 15 Jul 2024 20:05:31 +0200 Subject: [PATCH 06/53] introduce DynQuerySet, associated DynCommandEncoder methods --- wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/dynamic/command.rs | 51 ++++++++++++++++++++++++++++++++- wgpu-hal/src/dynamic/mod.rs | 1 + wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 4 +-- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ 8 files changed, 62 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index d3a9bd0c65..21fd1e367c 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -508,6 +508,8 @@ pub struct QuerySet { raw_ty: d3d12_ty::D3D12_QUERY_TYPE, } +impl crate::DynQuerySet for QuerySet {} + unsafe impl Send for QuerySet {} unsafe impl Sync for QuerySet {} diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index fbeedd1753..ef4cffb2b9 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,5 +1,8 @@ +use std::ops::Range; + use crate::{ - BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, Label, MemoryRange, + BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, DynQuerySet, Label, + MemoryRange, }; use super::{DynBuffer, DynResourceExt as _}; @@ -24,6 +27,19 @@ pub trait DynCommandEncoder: std::fmt::Debug { unsafe fn begin_debug_marker(&mut self, group_label: &str); unsafe fn end_debug_marker(&mut self); + unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32); + unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32); + unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32); + unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range); + unsafe fn copy_query_results( + &mut self, + set: &dyn DynQuerySet, + range: Range, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + stride: wgt::BufferSize, + ); + unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, @@ -90,6 +106,39 @@ impl DynCommandEncoder for C { } } + unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32) { + let set = set.expect_downcast_ref(); + unsafe { C::begin_query(self, set, index) }; + } + + unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32) { + let set = set.expect_downcast_ref(); + unsafe { C::end_query(self, set, index) }; + } + + unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32) { + let set = set.expect_downcast_ref(); + unsafe { C::write_timestamp(self, set, index) }; + } + + unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range) { + let set = set.expect_downcast_ref(); + unsafe { C::reset_queries(self, set, range) }; + } + + unsafe fn copy_query_results( + &mut self, + set: &dyn DynQuerySet, + range: Range, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + stride: wgt::BufferSize, + ) { + let set = set.expect_downcast_ref(); + let buffer = buffer.expect_downcast_ref(); + unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) }; + } + unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index f93cc82a9a..b3fa3d0965 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -87,6 +87,7 @@ impl DynResourceExt for R { } pub trait DynBuffer: DynResource + std::fmt::Debug {} +pub trait DynQuerySet: DynResource + std::fmt::Debug {} impl<'a> BufferBinding<'a, dyn DynBuffer> { pub fn expect_downcast(self) -> BufferBinding<'a, B> { diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index c4e2af8567..4dfb901551 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -43,6 +43,7 @@ impl crate::Api for Api { crate::impl_dyn_resource!(Context, Encoder, Resource); impl crate::DynBuffer for Resource {} +impl crate::DynQuerySet for Resource {} impl crate::Instance for Context { type A = Api; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index bf04c3a63c..8e3ff84b11 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -670,6 +670,8 @@ pub struct QuerySet { target: BindTarget, } +impl crate::DynQuerySet for QuerySet {} + #[derive(Debug)] pub struct Fence { last_completed: crate::FenceValue, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index ba943c5f8b..511da781d5 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -265,7 +265,7 @@ pub mod api { mod dynamic; pub(crate) use dynamic::{impl_dyn_resource, DynResource}; -pub use dynamic::{DynBuffer, DynCommandEncoder}; +pub use dynamic::{DynBuffer, DynCommandEncoder, DynQuerySet}; use std::{ borrow::{Borrow, Cow}, @@ -409,7 +409,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow; type TextureView: fmt::Debug + WasmNotSendSync; type Sampler: fmt::Debug + WasmNotSendSync; - type QuerySet: fmt::Debug + WasmNotSendSync; + type QuerySet: DynQuerySet; /// A value you can block on to wait for something to finish. /// diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index a7937731d2..82e8cd39e5 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -784,6 +784,8 @@ pub struct QuerySet { ty: wgt::QueryType, } +impl crate::DynQuerySet for QuerySet {} + unsafe impl Send for QuerySet {} unsafe impl Sync for QuerySet {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index f329551771..cb352382f3 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -833,6 +833,8 @@ pub struct QuerySet { raw: vk::QueryPool, } +impl crate::DynQuerySet for QuerySet {} + /// The [`Api::Fence`] type for [`vulkan::Api`]. /// /// This is an `enum` because there are two possible implementations of From 233d2ba4966ac4521000f8e9f7a2e51db02e59bf Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 15 Jul 2024 23:28:49 +0200 Subject: [PATCH 07/53] Introduce DynPipelineLayout & DynBindGroup --- wgpu-hal/src/dx12/mod.rs | 4 +++ wgpu-hal/src/dynamic/command.rs | 43 +++++++++++++++++++++++++++++++-- wgpu-hal/src/dynamic/mod.rs | 2 ++ wgpu-hal/src/empty.rs | 2 ++ wgpu-hal/src/gles/mod.rs | 4 +++ wgpu-hal/src/lib.rs | 6 ++--- wgpu-hal/src/metal/mod.rs | 4 +++ wgpu-hal/src/vulkan/mod.rs | 4 +++ 8 files changed, 64 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 21fd1e367c..aed7f1e9c6 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -550,6 +550,8 @@ pub struct BindGroup { dynamic_buffers: Vec, } +impl crate::DynBindGroup for BindGroup {} + bitflags::bitflags! { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct TableTypes: u8 { @@ -594,6 +596,8 @@ pub struct PipelineLayout { naga_options: naga::back::hlsl::Options, } +impl crate::DynPipelineLayout for PipelineLayout {} + #[derive(Debug)] pub struct ShaderModule { naga: crate::NagaShader, diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index ef4cffb2b9..05e231f1a0 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,8 +1,8 @@ use std::ops::Range; use crate::{ - BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, DynQuerySet, Label, - MemoryRange, + BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, DynBindGroup, + DynPipelineLayout, DynQuerySet, Label, MemoryRange, }; use super::{DynBuffer, DynResourceExt as _}; @@ -23,6 +23,22 @@ pub trait DynCommandEncoder: std::fmt::Debug { regions: &[BufferCopy], ); + unsafe fn set_bind_group( + &mut self, + layout: &dyn DynPipelineLayout, + index: u32, + group: &dyn DynBindGroup, + dynamic_offsets: &[wgt::DynamicOffset], + ); + + unsafe fn set_push_constants( + &mut self, + layout: &dyn DynPipelineLayout, + stages: wgt::ShaderStages, + offset_bytes: u32, + data: &[u32], + ); + unsafe fn insert_debug_marker(&mut self, label: &str); unsafe fn begin_debug_marker(&mut self, group_label: &str); unsafe fn end_debug_marker(&mut self); @@ -88,6 +104,29 @@ impl DynCommandEncoder for C { } } + unsafe fn set_bind_group( + &mut self, + layout: &dyn DynPipelineLayout, + index: u32, + group: &dyn DynBindGroup, + dynamic_offsets: &[wgt::DynamicOffset], + ) { + let layout = layout.expect_downcast_ref(); + let group = group.expect_downcast_ref(); + unsafe { C::set_bind_group(self, layout, index, group, dynamic_offsets) }; + } + + unsafe fn set_push_constants( + &mut self, + layout: &dyn DynPipelineLayout, + stages: wgt::ShaderStages, + offset_bytes: u32, + data: &[u32], + ) { + let layout = layout.expect_downcast_ref(); + unsafe { C::set_push_constants(self, layout, stages, offset_bytes, data) }; + } + unsafe fn insert_debug_marker(&mut self, label: &str) { unsafe { C::insert_debug_marker(self, label); diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index b3fa3d0965..7275c176be 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -86,7 +86,9 @@ impl DynResourceExt for R { } } +pub trait DynBindGroup: DynResource + std::fmt::Debug {} pub trait DynBuffer: DynResource + std::fmt::Debug {} +pub trait DynPipelineLayout: DynResource + std::fmt::Debug {} pub trait DynQuerySet: DynResource + std::fmt::Debug {} impl<'a> BufferBinding<'a, dyn DynBuffer> { diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 4dfb901551..51f751c213 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -42,7 +42,9 @@ impl crate::Api for Api { crate::impl_dyn_resource!(Context, Encoder, Resource); +impl crate::DynBindGroup for Resource {} impl crate::DynBuffer for Resource {} +impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::Instance for Context { diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 8e3ff84b11..e79a32097b 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -487,6 +487,8 @@ pub struct PipelineLayout { naga_options: naga::back::glsl::Options, } +impl crate::DynPipelineLayout for PipelineLayout {} + impl PipelineLayout { fn get_slot(&self, br: &naga::ResourceBinding) -> u8 { let group_info = &self.group_infos[br.group as usize]; @@ -525,6 +527,8 @@ pub struct BindGroup { contents: Box<[RawBinding]>, } +impl crate::DynBindGroup for BindGroup {} + type ShaderId = u32; #[derive(Debug)] diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 511da781d5..29e6e4a35f 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -265,7 +265,7 @@ pub mod api { mod dynamic; pub(crate) use dynamic::{impl_dyn_resource, DynResource}; -pub use dynamic::{DynBuffer, DynCommandEncoder, DynQuerySet}; +pub use dynamic::{DynBindGroup, DynBuffer, DynCommandEncoder, DynPipelineLayout, DynQuerySet}; use std::{ borrow::{Borrow, Cow}, @@ -431,8 +431,8 @@ pub trait Api: Clone + fmt::Debug + Sized { type Fence: fmt::Debug + WasmNotSendSync; type BindGroupLayout: fmt::Debug + WasmNotSendSync; - type BindGroup: fmt::Debug + WasmNotSendSync; - type PipelineLayout: fmt::Debug + WasmNotSendSync; + type BindGroup: DynBindGroup; + type PipelineLayout: DynPipelineLayout; type ShaderModule: fmt::Debug + WasmNotSendSync; type RenderPipeline: fmt::Debug + WasmNotSendSync; type ComputePipeline: fmt::Debug + WasmNotSendSync; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 82e8cd39e5..e25563a43f 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -624,6 +624,8 @@ pub struct PipelineLayout { per_stage_map: MultiStageResources, } +impl crate::DynPipelineLayout for PipelineLayout {} + trait AsNative { type Native; fn from(native: &Self::Native) -> Self; @@ -697,6 +699,8 @@ pub struct BindGroup { textures: Vec, } +impl crate::DynBindGroup for BindGroup {} + unsafe impl Send for BindGroup {} unsafe impl Sync for BindGroup {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index cb352382f3..ada874d81a 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -716,11 +716,15 @@ pub struct PipelineLayout { binding_arrays: naga::back::spv::BindingMap, } +impl crate::DynPipelineLayout for PipelineLayout {} + #[derive(Debug)] pub struct BindGroup { set: gpu_descriptor::DescriptorSet, } +impl crate::DynBindGroup for BindGroup {} + /// Miscellaneous allocation recycling pool for `CommandAllocator`. #[derive(Default)] struct Temp { From 65768388af58aedf69794a49616afd22454a58e8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 15 Jul 2024 23:34:17 +0200 Subject: [PATCH 08/53] Introduce DynComputePipeline & DynRenderPipeline --- wgpu-hal/src/dx12/mod.rs | 4 + wgpu-hal/src/dynamic/command.rs | 215 +++++++++++++++++++++++++++++++- wgpu-hal/src/dynamic/mod.rs | 2 + wgpu-hal/src/empty.rs | 2 + wgpu-hal/src/gles/mod.rs | 4 + wgpu-hal/src/lib.rs | 9 +- wgpu-hal/src/metal/mod.rs | 4 + wgpu-hal/src/vulkan/mod.rs | 4 + 8 files changed, 238 insertions(+), 6 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index aed7f1e9c6..c9ca02f977 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -629,6 +629,8 @@ pub struct RenderPipeline { vertex_strides: [Option; crate::MAX_VERTEX_BUFFERS], } +impl crate::DynRenderPipeline for RenderPipeline {} + unsafe impl Send for RenderPipeline {} unsafe impl Sync for RenderPipeline {} @@ -638,6 +640,8 @@ pub struct ComputePipeline { layout: PipelineLayoutShared, } +impl crate::DynComputePipeline for ComputePipeline {} + unsafe impl Send for ComputePipeline {} unsafe impl Sync for ComputePipeline {} diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index 05e231f1a0..b95aefa066 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,11 +1,13 @@ use std::ops::Range; use crate::{ - BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, DynBindGroup, - DynPipelineLayout, DynQuerySet, Label, MemoryRange, + BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, Label, MemoryRange, Rect, }; -use super::{DynBuffer, DynResourceExt as _}; +use super::{ + DynBindGroup, DynBuffer, DynComputePipeline, DynPipelineLayout, DynQuerySet, DynRenderPipeline, + DynResourceExt as _, +}; pub trait DynCommandEncoder: std::fmt::Debug { unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>; @@ -56,6 +58,8 @@ pub trait DynCommandEncoder: std::fmt::Debug { stride: wgt::BufferSize, ); + unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline); + unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, @@ -67,6 +71,75 @@ pub trait DynCommandEncoder: std::fmt::Debug { index: u32, binding: BufferBinding<'a, dyn DynBuffer>, ); + unsafe fn set_viewport(&mut self, rect: &Rect, depth_range: Range); + unsafe fn set_scissor_rect(&mut self, rect: &Rect); + unsafe fn set_stencil_reference(&mut self, value: u32); + unsafe fn set_blend_constants(&mut self, color: &[f32; 4]); + + unsafe fn draw( + &mut self, + first_vertex: u32, + vertex_count: u32, + first_instance: u32, + instance_count: u32, + ); + unsafe fn draw_indexed( + &mut self, + first_index: u32, + index_count: u32, + base_vertex: i32, + first_instance: u32, + instance_count: u32, + ); + unsafe fn draw_indirect( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + draw_count: u32, + ); + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + draw_count: u32, + ); + unsafe fn draw_indirect_count( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + count_buffer: &dyn DynBuffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ); + unsafe fn draw_indexed_indirect_count( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + count_buffer: &dyn DynBuffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ); + + // unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor); + // unsafe fn end_compute_pass(&mut self); + + unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline); + + unsafe fn dispatch(&mut self, count: [u32; 3]); + unsafe fn dispatch_indirect(&mut self, buffer: &dyn DynBuffer, offset: wgt::BufferAddress); + + // unsafe fn build_acceleration_structures<'a, T>( + // &mut self, + // descriptor_count: u32, + // descriptors: T, + // ) where + // Self::A: 'a, + // T: IntoIterator>; + + // unsafe fn place_acceleration_structure_barrier( + // &mut self, + // barrier: AccelerationStructureBarrier, + // ); } impl DynCommandEncoder for C { @@ -178,6 +251,142 @@ impl DynCommandEncoder for C { unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) }; } + unsafe fn set_viewport(&mut self, rect: &Rect, depth_range: Range) { + unsafe { + C::set_viewport(self, rect, depth_range); + } + } + + unsafe fn set_scissor_rect(&mut self, rect: &Rect) { + unsafe { + C::set_scissor_rect(self, rect); + } + } + + unsafe fn set_stencil_reference(&mut self, value: u32) { + unsafe { + C::set_stencil_reference(self, value); + } + } + + unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) { + unsafe { C::set_blend_constants(self, color) }; + } + + unsafe fn draw( + &mut self, + first_vertex: u32, + vertex_count: u32, + first_instance: u32, + instance_count: u32, + ) { + unsafe { + C::draw( + self, + first_vertex, + vertex_count, + first_instance, + instance_count, + ) + }; + } + + unsafe fn draw_indexed( + &mut self, + first_index: u32, + index_count: u32, + base_vertex: i32, + first_instance: u32, + instance_count: u32, + ) { + unsafe { + C::draw_indexed( + self, + first_index, + index_count, + base_vertex, + first_instance, + instance_count, + ) + }; + } + + unsafe fn draw_indirect( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + let buffer = buffer.expect_downcast_ref(); + unsafe { C::draw_indirect(self, buffer, offset, draw_count) }; + } + + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + let buffer = buffer.expect_downcast_ref(); + unsafe { C::draw_indexed_indirect(self, buffer, offset, draw_count) }; + } + + unsafe fn draw_indirect_count( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + count_buffer: &dyn DynBuffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + let buffer = buffer.expect_downcast_ref(); + let count_buffer = count_buffer.expect_downcast_ref(); + unsafe { + C::draw_indirect_count(self, buffer, offset, count_buffer, count_offset, max_count) + }; + } + + unsafe fn draw_indexed_indirect_count( + &mut self, + buffer: &dyn DynBuffer, + offset: wgt::BufferAddress, + count_buffer: &dyn DynBuffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + let buffer = buffer.expect_downcast_ref(); + let count_buffer = count_buffer.expect_downcast_ref(); + unsafe { + C::draw_indexed_indirect_count( + self, + buffer, + offset, + count_buffer, + count_offset, + max_count, + ) + }; + } + + unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline) { + let pipeline = pipeline.expect_downcast_ref(); + unsafe { C::set_compute_pipeline(self, pipeline) }; + } + + unsafe fn dispatch(&mut self, count: [u32; 3]) { + unsafe { C::dispatch(self, count) }; + } + + unsafe fn dispatch_indirect(&mut self, buffer: &dyn DynBuffer, offset: wgt::BufferAddress) { + let buffer = buffer.expect_downcast_ref(); + unsafe { C::dispatch_indirect(self, buffer, offset) }; + } + + unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline) { + let pipeline = pipeline.expect_downcast_ref(); + unsafe { C::set_render_pipeline(self, pipeline) }; + } + unsafe fn set_index_buffer<'a>( &mut self, binding: BufferBinding<'a, dyn DynBuffer>, diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 7275c176be..be342c42e9 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -90,6 +90,8 @@ pub trait DynBindGroup: DynResource + std::fmt::Debug {} pub trait DynBuffer: DynResource + std::fmt::Debug {} pub trait DynPipelineLayout: DynResource + std::fmt::Debug {} pub trait DynQuerySet: DynResource + std::fmt::Debug {} +pub trait DynRenderPipeline: DynResource + std::fmt::Debug {} +pub trait DynComputePipeline: DynResource + std::fmt::Debug {} impl<'a> BufferBinding<'a, dyn DynBuffer> { pub fn expect_downcast(self) -> BufferBinding<'a, B> { diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 51f751c213..06325e9a96 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -46,6 +46,8 @@ impl crate::DynBindGroup for Resource {} impl crate::DynBuffer for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} +impl crate::DynRenderPipeline for Resource {} +impl crate::DynComputePipeline for Resource {} impl crate::Instance for Context { type A = Api; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index e79a32097b..940a8e6791 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -653,6 +653,8 @@ pub struct RenderPipeline { alpha_to_coverage_enabled: bool, } +impl crate::DynRenderPipeline for RenderPipeline {} + #[cfg(send_sync)] unsafe impl Sync for RenderPipeline {} #[cfg(send_sync)] @@ -663,6 +665,8 @@ pub struct ComputePipeline { inner: Arc, } +impl crate::DynComputePipeline for ComputePipeline {} + #[cfg(send_sync)] unsafe impl Sync for ComputePipeline {} #[cfg(send_sync)] diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 29e6e4a35f..e348d86c22 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -265,7 +265,10 @@ pub mod api { mod dynamic; pub(crate) use dynamic::{impl_dyn_resource, DynResource}; -pub use dynamic::{DynBindGroup, DynBuffer, DynCommandEncoder, DynPipelineLayout, DynQuerySet}; +pub use dynamic::{ + DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynPipelineLayout, DynQuerySet, + DynRenderPipeline, +}; use std::{ borrow::{Borrow, Cow}, @@ -434,8 +437,8 @@ pub trait Api: Clone + fmt::Debug + Sized { type BindGroup: DynBindGroup; type PipelineLayout: DynPipelineLayout; type ShaderModule: fmt::Debug + WasmNotSendSync; - type RenderPipeline: fmt::Debug + WasmNotSendSync; - type ComputePipeline: fmt::Debug + WasmNotSendSync; + type RenderPipeline: DynRenderPipeline; + type ComputePipeline: DynComputePipeline; type PipelineCache: fmt::Debug + WasmNotSendSync; type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index e25563a43f..be4b7c23bd 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -767,6 +767,8 @@ pub struct RenderPipeline { unsafe impl Send for RenderPipeline {} unsafe impl Sync for RenderPipeline {} +impl crate::DynRenderPipeline for RenderPipeline {} + #[derive(Debug)] pub struct ComputePipeline { raw: metal::ComputePipelineState, @@ -780,6 +782,8 @@ pub struct ComputePipeline { unsafe impl Send for ComputePipeline {} unsafe impl Sync for ComputePipeline {} +impl crate::DynComputePipeline for ComputePipeline {} + #[derive(Debug, Clone)] pub struct QuerySet { raw_buffer: metal::Buffer, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index ada874d81a..b8b6690574 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -822,11 +822,15 @@ pub struct RenderPipeline { raw: vk::Pipeline, } +impl crate::DynRenderPipeline for RenderPipeline {} + #[derive(Debug)] pub struct ComputePipeline { raw: vk::Pipeline, } +impl crate::DynComputePipeline for ComputePipeline {} + #[derive(Debug)] pub struct PipelineCache { raw: vk::PipelineCache, From 7548973845fab254ba131dd0c6bd0db7850111e5 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 15 Jul 2024 23:42:39 +0200 Subject: [PATCH 09/53] fold ComputePassTimestampWrites & RenderPassTimestampWrites and make PassTimestampWrites usable with DynQuerySet --- wgpu-core/src/command/compute.rs | 2 +- wgpu-core/src/command/render.rs | 2 +- wgpu-hal/src/lib.rs | 39 ++++---------------------------- 3 files changed, 7 insertions(+), 36 deletions(-) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 39fe1d91d1..c31db544d1 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -511,7 +511,7 @@ impl Global { } } - Some(hal::ComputePassTimestampWrites { + 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, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 86a9eef26f..a943a902af 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1192,7 +1192,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { pending_query_resets.use_query_set(query_set, index); } - Some(hal::RenderPassTimestampWrites { + 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, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index e348d86c22..07ce7c7e83 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -2074,24 +2074,13 @@ pub struct DepthStencilAttachment<'a, A: Api> { pub clear_value: (f32, u32), } -#[derive(Debug)] -pub struct RenderPassTimestampWrites<'a, A: Api> { - pub query_set: &'a A::QuerySet, +#[derive(Clone, Debug)] +pub struct PassTimestampWrites<'a, Q: DynQuerySet + ?Sized> { + pub query_set: &'a Q, pub beginning_of_pass_write_index: Option, pub end_of_pass_write_index: Option, } -// Rust gets confused about the impl requirements for `A` -impl Clone for RenderPassTimestampWrites<'_, A> { - fn clone(&self) -> Self { - Self { - query_set: self.query_set, - beginning_of_pass_write_index: self.beginning_of_pass_write_index, - end_of_pass_write_index: self.end_of_pass_write_index, - } - } -} - #[derive(Clone, Debug)] pub struct RenderPassDescriptor<'a, A: Api> { pub label: Label<'a>, @@ -2100,32 +2089,14 @@ pub struct RenderPassDescriptor<'a, A: Api> { pub color_attachments: &'a [Option>], pub depth_stencil_attachment: Option>, pub multiview: Option, - pub timestamp_writes: Option>, + pub timestamp_writes: Option>, pub occlusion_query_set: Option<&'a A::QuerySet>, } -#[derive(Debug)] -pub struct ComputePassTimestampWrites<'a, A: Api> { - pub query_set: &'a A::QuerySet, - pub beginning_of_pass_write_index: Option, - pub end_of_pass_write_index: Option, -} - -// Rust gets confused about the impl requirements for `A` -impl Clone for ComputePassTimestampWrites<'_, A> { - fn clone(&self) -> Self { - Self { - query_set: self.query_set, - beginning_of_pass_write_index: self.beginning_of_pass_write_index, - end_of_pass_write_index: self.end_of_pass_write_index, - } - } -} - #[derive(Clone, Debug)] pub struct ComputePassDescriptor<'a, A: Api> { pub label: Label<'a>, - pub timestamp_writes: Option>, + pub timestamp_writes: Option>, } /// Stores the text of any validation errors that have occurred since From ff49edc8a41127e883bf39e8ac257a04861e9580 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 17 Jul 2024 09:39:29 +0200 Subject: [PATCH 10/53] introduce DynTexture & DynTextureView --- wgpu-hal/src/dx12/mod.rs | 4 ++++ wgpu-hal/src/dynamic/mod.rs | 4 +++- wgpu-hal/src/empty.rs | 4 +++- wgpu-hal/src/gles/mod.rs | 4 ++++ wgpu-hal/src/lib.rs | 6 +++--- wgpu-hal/src/metal/mod.rs | 4 ++++ wgpu-hal/src/vulkan/mod.rs | 4 ++++ 7 files changed, 25 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index c9ca02f977..3dbb58abb0 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -452,6 +452,8 @@ pub struct Texture { allocation: Option, } +impl crate::DynTexture for Texture {} + unsafe impl Send for Texture {} unsafe impl Sync for Texture {} @@ -491,6 +493,8 @@ pub struct TextureView { handle_dsv_rw: Option, } +impl crate::DynTextureView for TextureView {} + unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index be342c42e9..10cea187c5 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -88,10 +88,12 @@ impl DynResourceExt for R { pub trait DynBindGroup: DynResource + std::fmt::Debug {} pub trait DynBuffer: DynResource + std::fmt::Debug {} +pub trait DynComputePipeline: DynResource + std::fmt::Debug {} pub trait DynPipelineLayout: DynResource + std::fmt::Debug {} pub trait DynQuerySet: DynResource + std::fmt::Debug {} pub trait DynRenderPipeline: DynResource + std::fmt::Debug {} -pub trait DynComputePipeline: DynResource + std::fmt::Debug {} +pub trait DynTexture: DynResource + std::fmt::Debug {} +pub trait DynTextureView: DynResource + std::fmt::Debug {} impl<'a> BufferBinding<'a, dyn DynBuffer> { pub fn expect_downcast(self) -> BufferBinding<'a, B> { diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 06325e9a96..f63df91e9d 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -44,10 +44,12 @@ crate::impl_dyn_resource!(Context, Encoder, Resource); impl crate::DynBindGroup for Resource {} impl crate::DynBuffer for Resource {} +impl crate::DynComputePipeline for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} -impl crate::DynComputePipeline for Resource {} +impl crate::DynTexture for Resource {} +impl crate::DynTextureView for Resource {} impl crate::Instance for Context { type A = Api; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 940a8e6791..5709735202 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -373,6 +373,8 @@ pub struct Texture { pub copy_size: CopyExtent, } +impl crate::DynTexture for Texture {} + impl Texture { pub fn default_framebuffer(format: wgt::TextureFormat) -> Self { Self { @@ -460,6 +462,8 @@ pub struct TextureView { format: wgt::TextureFormat, } +impl crate::DynTextureView for TextureView {} + #[derive(Debug)] pub struct Sampler { raw: glow::Sampler, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 07ce7c7e83..ab119fc357 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -267,7 +267,7 @@ mod dynamic; pub(crate) use dynamic::{impl_dyn_resource, DynResource}; pub use dynamic::{ DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynPipelineLayout, DynQuerySet, - DynRenderPipeline, + DynRenderPipeline, DynTexture, DynTextureView, }; use std::{ @@ -408,9 +408,9 @@ pub trait Api: Clone + fmt::Debug + Sized { type CommandBuffer: WasmNotSendSync + fmt::Debug; type Buffer: DynBuffer; - type Texture: fmt::Debug + WasmNotSendSync + 'static; + type Texture: DynTexture; type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow; - type TextureView: fmt::Debug + WasmNotSendSync; + type TextureView: DynTextureView; type Sampler: fmt::Debug + WasmNotSendSync; type QuerySet: DynQuerySet; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index be4b7c23bd..a7282ca4cd 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -505,6 +505,8 @@ pub struct Texture { copy_size: crate::CopyExtent, } +impl crate::DynTexture for Texture {} + unsafe impl Send for Texture {} unsafe impl Sync for Texture {} @@ -514,6 +516,8 @@ pub struct TextureView { aspects: crate::FormatAspects, } +impl crate::DynTextureView for TextureView {} + unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index b8b6690574..2d4a971739 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -671,6 +671,8 @@ pub struct Texture { view_formats: Vec, } +impl crate::DynTexture for Texture {} + impl Texture { /// # Safety /// @@ -687,6 +689,8 @@ pub struct TextureView { attachment: FramebufferAttachment, } +impl crate::DynTextureView for TextureView {} + impl TextureView { /// # Safety /// From 15748cb2a120618df1ba925be37b97594a0e6bdc Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 17 Jul 2024 09:51:53 +0200 Subject: [PATCH 11/53] render/compute pass descriptors work now with dyn types --- wgpu-core/src/command/render.rs | 2 +- wgpu-hal/src/dx12/command.rs | 7 ++-- wgpu-hal/src/empty.rs | 5 +-- wgpu-hal/src/gles/command.rs | 7 ++-- wgpu-hal/src/lib.rs | 64 +++++++++++++-------------------- wgpu-hal/src/metal/command.rs | 7 ++-- wgpu-hal/src/vulkan/command.rs | 10 ++++-- wgpu-hal/src/vulkan/conv.rs | 4 +-- 8 files changed, 53 insertions(+), 53 deletions(-) diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index a943a902af..73ce837ba9 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1041,7 +1041,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { } let mut color_attachments_hal = - ArrayVec::>, { hal::MAX_COLOR_ATTACHMENTS }>::new(); + ArrayVec::>, { hal::MAX_COLOR_ATTACHMENTS }>::new(); for (index, attachment) in color_attachments.iter().enumerate() { let at = if let Some(attachment) = attachment.as_ref() { attachment diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index c5978e55e4..bb50720f9a 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -661,7 +661,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // render - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { + unsafe fn begin_render_pass( + &mut self, + desc: &crate::RenderPassDescriptor, + ) { unsafe { self.begin_pass(super::PassKind::Render, desc.label) }; // Start timestamp if any (before all other commands but after debug marker) @@ -1130,7 +1133,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn begin_compute_pass<'a>( &mut self, - desc: &crate::ComputePassDescriptor<'a, super::Api>, + desc: &crate::ComputePassDescriptor<'a, super::QuerySet>, ) { unsafe { self.begin_pass(super::PassKind::Compute, desc.label) }; diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index f63df91e9d..7a9cc9e714 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -370,7 +370,8 @@ impl crate::CommandEncoder for Encoder { // render - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) {} + unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { + } unsafe fn end_render_pass(&mut self) {} unsafe fn set_bind_group( @@ -465,7 +466,7 @@ impl crate::CommandEncoder for Encoder { // compute - unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {} + unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {} unsafe fn end_compute_pass(&mut self) {} unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {} diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index e7e3714038..eb452e598b 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -494,7 +494,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // render - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { + unsafe fn begin_render_pass( + &mut self, + desc: &crate::RenderPassDescriptor, + ) { debug_assert!(self.state.end_of_pass_timestamp.is_none()); if let Some(ref t) = desc.timestamp_writes { if let Some(index) = t.beginning_of_pass_write_index { @@ -1137,7 +1140,7 @@ impl crate::CommandEncoder for super::CommandEncoder { // compute - unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) { + unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) { debug_assert!(self.state.end_of_pass_timestamp.is_none()); if let Some(ref t) = desc.timestamp_writes { if let Some(index) = t.beginning_of_pass_write_index { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index ab119fc357..d14d33771a 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1231,7 +1231,10 @@ pub trait CommandEncoder: WasmNotSendSync + fmt::Debug { // render passes // Begins a render pass, clears all active bindings. - unsafe fn begin_render_pass(&mut self, desc: &RenderPassDescriptor); + unsafe fn begin_render_pass( + &mut self, + desc: &RenderPassDescriptor<::QuerySet, ::TextureView>, + ); unsafe fn end_render_pass(&mut self); unsafe fn set_render_pipeline(&mut self, pipeline: &::RenderPipeline); @@ -1298,7 +1301,10 @@ pub trait CommandEncoder: WasmNotSendSync + fmt::Debug { // compute passes // Begins a compute pass, clears all active bindings. - unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor); + unsafe fn begin_compute_pass( + &mut self, + desc: &ComputePassDescriptor<::QuerySet>, + ); unsafe fn end_compute_pass(&mut self); unsafe fn set_compute_pipeline(&mut self, pipeline: &::ComputePipeline); @@ -2028,47 +2034,25 @@ pub struct BufferTextureCopy { pub size: CopyExtent, } -#[derive(Debug)] -pub struct Attachment<'a, A: Api> { - pub view: &'a A::TextureView, +#[derive(Clone, Debug)] +pub struct Attachment<'a, T: DynTextureView + ?Sized> { + pub view: &'a T, /// Contains either a single mutating usage as a target, /// or a valid combination of read-only usages. pub usage: TextureUses, } -// Rust gets confused about the impl requirements for `A` -impl Clone for Attachment<'_, A> { - fn clone(&self) -> Self { - Self { - view: self.view, - usage: self.usage, - } - } -} - -#[derive(Debug)] -pub struct ColorAttachment<'a, A: Api> { - pub target: Attachment<'a, A>, - pub resolve_target: Option>, +#[derive(Clone, Debug)] +pub struct ColorAttachment<'a, T: DynTextureView + ?Sized> { + pub target: Attachment<'a, T>, + pub resolve_target: Option>, pub ops: AttachmentOps, pub clear_value: wgt::Color, } -// Rust gets confused about the impl requirements for `A` -impl Clone for ColorAttachment<'_, A> { - fn clone(&self) -> Self { - Self { - target: self.target.clone(), - resolve_target: self.resolve_target.clone(), - ops: self.ops, - clear_value: self.clear_value, - } - } -} - #[derive(Clone, Debug)] -pub struct DepthStencilAttachment<'a, A: Api> { - pub target: Attachment<'a, A>, +pub struct DepthStencilAttachment<'a, T: DynTextureView + ?Sized> { + pub target: Attachment<'a, T>, pub depth_ops: AttachmentOps, pub stencil_ops: AttachmentOps, pub clear_value: (f32, u32), @@ -2082,21 +2066,21 @@ pub struct PassTimestampWrites<'a, Q: DynQuerySet + ?Sized> { } #[derive(Clone, Debug)] -pub struct RenderPassDescriptor<'a, A: Api> { +pub struct RenderPassDescriptor<'a, Q: DynQuerySet + ?Sized, T: DynTextureView + ?Sized> { pub label: Label<'a>, pub extent: wgt::Extent3d, pub sample_count: u32, - pub color_attachments: &'a [Option>], - pub depth_stencil_attachment: Option>, + pub color_attachments: &'a [Option>], + pub depth_stencil_attachment: Option>, pub multiview: Option, - pub timestamp_writes: Option>, - pub occlusion_query_set: Option<&'a A::QuerySet>, + pub timestamp_writes: Option>, + pub occlusion_query_set: Option<&'a Q>, } #[derive(Clone, Debug)] -pub struct ComputePassDescriptor<'a, A: Api> { +pub struct ComputePassDescriptor<'a, Q: DynQuerySet + ?Sized> { pub label: Label<'a>, - pub timestamp_writes: Option>, + pub timestamp_writes: Option>, } /// Stores the text of any validation errors that have occurred since diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index db19727a5f..204f5328c5 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -501,7 +501,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // render - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { + unsafe fn begin_render_pass( + &mut self, + desc: &crate::RenderPassDescriptor, + ) { self.begin_pass(); self.state.index = None; @@ -1128,7 +1131,7 @@ impl crate::CommandEncoder for super::CommandEncoder { // compute - unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) { + unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) { self.begin_pass(); debug_assert!(self.state.blit.is_none()); diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index ddce6c24ed..79cafac7c0 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -644,7 +644,10 @@ impl crate::CommandEncoder for super::CommandEncoder { } // render - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) { + unsafe fn begin_render_pass( + &mut self, + desc: &crate::RenderPassDescriptor, + ) { let mut vk_clear_values = ArrayVec::::new(); let mut vk_image_views = ArrayVec::::new(); @@ -1067,7 +1070,10 @@ impl crate::CommandEncoder for super::CommandEncoder { // compute - unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor<'_, super::Api>) { + unsafe fn begin_compute_pass( + &mut self, + desc: &crate::ComputePassDescriptor<'_, super::QuerySet>, + ) { self.bind_point = vk::PipelineBindPoint::COMPUTE; if let Some(label) = desc.label { unsafe { self.begin_debug_marker(label) }; diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 87757c42d5..38642ba082 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -178,7 +178,7 @@ pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option { +impl crate::Attachment<'_, super::TextureView> { pub(super) fn make_attachment_key( &self, ops: crate::AttachmentOps, @@ -192,7 +192,7 @@ impl crate::Attachment<'_, super::Api> { } } -impl crate::ColorAttachment<'_, super::Api> { +impl crate::ColorAttachment<'_, super::TextureView> { pub(super) unsafe fn make_vk_clear_color(&self) -> vk::ClearColorValue { let cv = &self.clear_value; match self From c19659b5428972949523ccf53831cc977f2e5f4c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 10:13:17 +0200 Subject: [PATCH 12/53] implement begin/end render/computepass for dyncommandencoder --- wgpu-hal/src/dynamic/command.rs | 114 ++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index b95aefa066..6b5b54fd2b 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,12 +1,14 @@ use std::ops::Range; use crate::{ - BufferBarrier, BufferBinding, BufferCopy, CommandEncoder, DeviceError, Label, MemoryRange, Rect, + Api, Attachment, BufferBarrier, BufferBinding, BufferCopy, ColorAttachment, CommandEncoder, + ComputePassDescriptor, DepthStencilAttachment, DeviceError, Label, MemoryRange, + PassTimestampWrites, Rect, RenderPassDescriptor, }; use super::{ DynBindGroup, DynBuffer, DynComputePipeline, DynPipelineLayout, DynQuerySet, DynRenderPipeline, - DynResourceExt as _, + DynResourceExt as _, DynTextureView, }; pub trait DynCommandEncoder: std::fmt::Debug { @@ -58,6 +60,12 @@ pub trait DynCommandEncoder: std::fmt::Debug { stride: wgt::BufferSize, ); + unsafe fn begin_render_pass( + &mut self, + desc: &RenderPassDescriptor, + ); + unsafe fn end_render_pass(&mut self); + unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline); unsafe fn set_index_buffer<'a>( @@ -120,8 +128,8 @@ pub trait DynCommandEncoder: std::fmt::Debug { max_count: u32, ); - // unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor); - // unsafe fn end_compute_pass(&mut self); + unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor); + unsafe fn end_compute_pass(&mut self); unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline); @@ -251,6 +259,48 @@ impl DynCommandEncoder for C { unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) }; } + unsafe fn begin_render_pass( + &mut self, + desc: &RenderPassDescriptor, + ) { + let color_attachments = desc + .color_attachments + .iter() + .map(|attachment| { + attachment + .as_ref() + .map(|attachment| attachment.expect_downcast()) + }) + .collect::>(); + + let desc: RenderPassDescriptor<::QuerySet, ::TextureView> = + RenderPassDescriptor { + label: desc.label, + extent: desc.extent, + sample_count: desc.sample_count, + color_attachments: &color_attachments, + depth_stencil_attachment: desc + .depth_stencil_attachment + .as_ref() + .map(|ds| ds.expect_downcast()), + multiview: desc.multiview, + timestamp_writes: desc + .timestamp_writes + .as_ref() + .map(|writes| writes.expect_downcast()), + occlusion_query_set: desc + .occlusion_query_set + .map(|set| set.expect_downcast_ref()), + }; + unsafe { C::begin_render_pass(self, &desc) }; + } + + unsafe fn end_render_pass(&mut self) { + unsafe { + C::end_render_pass(self); + } + } + unsafe fn set_viewport(&mut self, rect: &Rect, depth_range: Range) { unsafe { C::set_viewport(self, rect, depth_range); @@ -368,6 +418,21 @@ impl DynCommandEncoder for C { }; } + unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor) { + let desc = ComputePassDescriptor { + label: desc.label, + timestamp_writes: desc + .timestamp_writes + .as_ref() + .map(|writes| writes.expect_downcast()), + }; + unsafe { C::begin_compute_pass(self, &desc) }; + } + + unsafe fn end_compute_pass(&mut self) { + unsafe { C::end_compute_pass(self) }; + } + unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline) { let pipeline = pipeline.expect_downcast_ref(); unsafe { C::set_compute_pipeline(self, pipeline) }; @@ -405,3 +470,44 @@ impl DynCommandEncoder for C { unsafe { self.set_vertex_buffer(index, binding) }; } } + +impl<'a> PassTimestampWrites<'a, dyn DynQuerySet> { + pub fn expect_downcast(&self) -> PassTimestampWrites<'a, B> { + PassTimestampWrites { + query_set: self.query_set.expect_downcast_ref(), + beginning_of_pass_write_index: self.beginning_of_pass_write_index, + end_of_pass_write_index: self.end_of_pass_write_index, + } + } +} + +impl<'a> Attachment<'a, dyn DynTextureView> { + pub fn expect_downcast(&self) -> Attachment<'a, B> { + Attachment { + view: self.view.expect_downcast_ref(), + usage: self.usage, + } + } +} + +impl<'a> ColorAttachment<'a, dyn DynTextureView> { + pub fn expect_downcast(&self) -> ColorAttachment<'a, B> { + ColorAttachment { + target: self.target.expect_downcast(), + resolve_target: self.resolve_target.as_ref().map(|rt| rt.expect_downcast()), + ops: self.ops, + clear_value: self.clear_value, + } + } +} + +impl<'a> DepthStencilAttachment<'a, dyn DynTextureView> { + pub fn expect_downcast(&self) -> DepthStencilAttachment<'a, B> { + DepthStencilAttachment { + target: self.target.expect_downcast(), + depth_ops: self.depth_ops, + stencil_ops: self.stencil_ops, + clear_value: self.clear_value, + } + } +} From 1ee9d4b0f2b1f00faeea62ec309932570a406e73 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 10:46:13 +0200 Subject: [PATCH 13/53] implement transition_textures for DynCommandEncoder --- wgpu-core/src/track/mod.rs | 5 ++++- wgpu-core/src/track/texture.rs | 4 ++-- wgpu-hal/src/dx12/command.rs | 2 +- wgpu-hal/src/dynamic/command.rs | 14 ++++++++++++-- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/command.rs | 2 +- wgpu-hal/src/lib.rs | 6 +++--- wgpu-hal/src/metal/command.rs | 2 +- wgpu-hal/src/vulkan/command.rs | 2 +- 9 files changed, 26 insertions(+), 13 deletions(-) diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 5f7a868251..4fccb24abe 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -272,7 +272,10 @@ impl PendingTransition { impl PendingTransition { /// Produce the hal barrier corresponding to the transition. - pub fn into_hal<'a, A: HalApi>(self, texture: &'a A::Texture) -> hal::TextureBarrier<'a, A> { + pub fn into_hal<'a, T: hal::DynTexture + ?Sized>( + self, + texture: &'a T, + ) -> hal::TextureBarrier<'a, T> { // These showing up in a barrier is always a bug strict_assert_ne!(self.usage.start, hal::TextureUses::UNKNOWN); strict_assert_ne!(self.usage.end, hal::TextureUses::UNKNOWN); diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index 243bd25207..f454c3e225 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -754,7 +754,7 @@ impl DeviceTextureTracker { &'a mut self, tracker: &'a TextureTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); @@ -798,7 +798,7 @@ impl DeviceTextureTracker { &'a mut self, scope: &'a TextureUsageScope, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in scope.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index bb50720f9a..cf2147d0ca 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -359,7 +359,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { self.temp.barriers.clear(); diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index 6b5b54fd2b..7f670b3fc7 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -3,12 +3,12 @@ use std::ops::Range; use crate::{ Api, Attachment, BufferBarrier, BufferBinding, BufferCopy, ColorAttachment, CommandEncoder, ComputePassDescriptor, DepthStencilAttachment, DeviceError, Label, MemoryRange, - PassTimestampWrites, Rect, RenderPassDescriptor, + PassTimestampWrites, Rect, RenderPassDescriptor, TextureBarrier, }; use super::{ DynBindGroup, DynBuffer, DynComputePipeline, DynPipelineLayout, DynQuerySet, DynRenderPipeline, - DynResourceExt as _, DynTextureView, + DynResourceExt as _, DynTexture, DynTextureView, }; pub trait DynCommandEncoder: std::fmt::Debug { @@ -17,6 +17,7 @@ pub trait DynCommandEncoder: std::fmt::Debug { unsafe fn discard_encoding(&mut self); unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]); + unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]); unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange); @@ -167,6 +168,15 @@ impl DynCommandEncoder for C { unsafe { self.transition_buffers(barriers) }; } + unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]) { + let barriers = barriers.iter().map(|barrier| TextureBarrier { + texture: barrier.texture.expect_downcast_ref(), + usage: barrier.usage.clone(), + range: barrier.range, + }); + unsafe { self.transition_textures(barriers) }; + } + unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange) { let buffer = buffer.expect_downcast_ref(); unsafe { C::clear_buffer(self, buffer, range) }; diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 7a9cc9e714..d39d41adca 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -314,7 +314,7 @@ impl crate::CommandEncoder for Encoder { unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { } diff --git a/wgpu-hal/src/gles/command.rs b/wgpu-hal/src/gles/command.rs index eb452e598b..cd62726050 100644 --- a/wgpu-hal/src/gles/command.rs +++ b/wgpu-hal/src/gles/command.rs @@ -298,7 +298,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { if !self .private_caps diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index d14d33771a..60829f5e43 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1110,7 +1110,7 @@ pub trait CommandEncoder: WasmNotSendSync + fmt::Debug { unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where - T: Iterator>; + T: Iterator::Texture>>; // copy operations @@ -1990,8 +1990,8 @@ pub struct BufferBarrier<'a, B: DynBuffer + ?Sized> { } #[derive(Debug, Clone)] -pub struct TextureBarrier<'a, A: Api> { - pub texture: &'a A::Texture, +pub struct TextureBarrier<'a, T: DynTexture + ?Sized> { + pub texture: &'a T, pub range: wgt::ImageSubresourceRange, pub usage: Range, } diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 204f5328c5..22a72739d6 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -247,7 +247,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_textures<'a, T>(&mut self, _barriers: T) where - T: Iterator>, + T: Iterator>, { } diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 79cafac7c0..b7f4306f69 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -156,7 +156,7 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe fn transition_textures<'a, T>(&mut self, barriers: T) where - T: Iterator>, + T: Iterator>, { let mut src_stages = vk::PipelineStageFlags::empty(); let mut dst_stages = vk::PipelineStageFlags::empty(); From 8bb009ec56a3e08c88ac960991b5532bb78abac3 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 10:55:03 +0200 Subject: [PATCH 14/53] buffer / texture copy operations for DynCommandEncoder --- wgpu-hal/src/dynamic/command.rs | 70 +++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index 7f670b3fc7..4100f33ac9 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -1,9 +1,9 @@ use std::ops::Range; use crate::{ - Api, Attachment, BufferBarrier, BufferBinding, BufferCopy, ColorAttachment, CommandEncoder, - ComputePassDescriptor, DepthStencilAttachment, DeviceError, Label, MemoryRange, - PassTimestampWrites, Rect, RenderPassDescriptor, TextureBarrier, + Api, Attachment, BufferBarrier, BufferBinding, BufferCopy, BufferTextureCopy, ColorAttachment, + CommandEncoder, ComputePassDescriptor, DepthStencilAttachment, DeviceError, Label, MemoryRange, + PassTimestampWrites, Rect, RenderPassDescriptor, TextureBarrier, TextureCopy, TextureUses, }; use super::{ @@ -28,6 +28,29 @@ pub trait DynCommandEncoder: std::fmt::Debug { regions: &[BufferCopy], ); + unsafe fn copy_texture_to_texture( + &mut self, + src: &dyn DynTexture, + src_usage: TextureUses, + dst: &dyn DynTexture, + regions: &[TextureCopy], + ); + + unsafe fn copy_buffer_to_texture( + &mut self, + src: &dyn DynBuffer, + dst: &dyn DynTexture, + regions: &[BufferTextureCopy], + ); + + unsafe fn copy_texture_to_buffer( + &mut self, + src: &dyn DynTexture, + src_usage: TextureUses, + dst: &dyn DynBuffer, + regions: &[BufferTextureCopy], + ); + unsafe fn set_bind_group( &mut self, layout: &dyn DynPipelineLayout, @@ -195,6 +218,47 @@ impl DynCommandEncoder for C { } } + unsafe fn copy_texture_to_texture( + &mut self, + src: &dyn DynTexture, + src_usage: TextureUses, + dst: &dyn DynTexture, + regions: &[TextureCopy], + ) { + let src = src.expect_downcast_ref(); + let dst = dst.expect_downcast_ref(); + unsafe { + C::copy_texture_to_texture(self, src, src_usage, dst, regions.iter().cloned()); + } + } + + unsafe fn copy_buffer_to_texture( + &mut self, + src: &dyn DynBuffer, + dst: &dyn DynTexture, + regions: &[BufferTextureCopy], + ) { + let src = src.expect_downcast_ref(); + let dst = dst.expect_downcast_ref(); + unsafe { + C::copy_buffer_to_texture(self, src, dst, regions.iter().cloned()); + } + } + + unsafe fn copy_texture_to_buffer( + &mut self, + src: &dyn DynTexture, + src_usage: TextureUses, + dst: &dyn DynBuffer, + regions: &[BufferTextureCopy], + ) { + let src = src.expect_downcast_ref(); + let dst = dst.expect_downcast_ref(); + unsafe { + C::copy_texture_to_buffer(self, src, src_usage, dst, regions.iter().cloned()); + } + } + unsafe fn set_bind_group( &mut self, layout: &dyn DynPipelineLayout, From 5719e385f65e01079aa2e024ea6999ab169c534d Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 11:45:22 +0200 Subject: [PATCH 15/53] texture & buffer transitioning always uses DynCommandEncoder now collateral: ComputePass uses DynCommandEncoder during recording --- wgpu-hal/src/dynamic/command.rs | 6 +++--- wgpu-hal/src/lib.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wgpu-hal/src/dynamic/command.rs b/wgpu-hal/src/dynamic/command.rs index 4100f33ac9..ae41b1bb7b 100644 --- a/wgpu-hal/src/dynamic/command.rs +++ b/wgpu-hal/src/dynamic/command.rs @@ -8,10 +8,10 @@ use crate::{ use super::{ DynBindGroup, DynBuffer, DynComputePipeline, DynPipelineLayout, DynQuerySet, DynRenderPipeline, - DynResourceExt as _, DynTexture, DynTextureView, + DynResource, DynResourceExt as _, DynTexture, DynTextureView, }; -pub trait DynCommandEncoder: std::fmt::Debug { +pub trait DynCommandEncoder: DynResource + std::fmt::Debug { unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>; unsafe fn discard_encoding(&mut self); @@ -174,7 +174,7 @@ pub trait DynCommandEncoder: std::fmt::Debug { // ); } -impl DynCommandEncoder for C { +impl DynCommandEncoder for C { unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError> { unsafe { C::begin_encoding(self, label) } } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 60829f5e43..ca6313342c 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -264,10 +264,10 @@ pub mod api { mod dynamic; -pub(crate) use dynamic::{impl_dyn_resource, DynResource}; +pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynPipelineLayout, DynQuerySet, - DynRenderPipeline, DynTexture, DynTextureView, + DynRenderPipeline, DynResource, DynTexture, DynTextureView, }; use std::{ From 2502283e54474a8a932c214791bf295473f6522f Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 20:57:42 +0200 Subject: [PATCH 16/53] Introduce DynDevice --- wgpu-hal/src/dynamic/device.rs | 13 +++++++++++++ wgpu-hal/src/dynamic/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 4 ++-- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 wgpu-hal/src/dynamic/device.rs diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs new file mode 100644 index 0000000000..30e245867c --- /dev/null +++ b/wgpu-hal/src/dynamic/device.rs @@ -0,0 +1,13 @@ +use crate::{Device, DynBuffer}; + +use super::DynResourceExt; + +pub trait DynDevice { + unsafe fn destroy_buffer(&self, buffer: Box); +} + +impl DynDevice for D { + unsafe fn destroy_buffer(&self, buffer: Box) { + unsafe { D::destroy_buffer(self, buffer.unbox()) }; + } +} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 10cea187c5..405f5c5e89 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -1,6 +1,8 @@ mod command; +mod device; pub use self::command::DynCommandEncoder; +pub use self::device::DynDevice; use std::any::Any; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index ca6313342c..2b628b2bc1 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -266,8 +266,8 @@ mod dynamic; pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ - DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynPipelineLayout, DynQuerySet, - DynRenderPipeline, DynResource, DynTexture, DynTextureView, + DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynDevice, DynPipelineLayout, + DynQuerySet, DynRenderPipeline, DynResource, DynTexture, DynTextureView, }; use std::{ From 7b253892ab4a2292ddc92790c95505046fa76363 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 21:12:42 +0200 Subject: [PATCH 17/53] add most remaining dyn type traits --- wgpu-hal/src/dynamic/mod.rs | 6 ++++++ wgpu-hal/src/lib.rs | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 405f5c5e89..cb114af9f1 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -88,12 +88,18 @@ impl DynResourceExt for R { } } +pub trait DynAccelerationStructure: DynResource + std::fmt::Debug {} pub trait DynBindGroup: DynResource + std::fmt::Debug {} +pub trait DynBindGroupLayout: DynResource + std::fmt::Debug {} pub trait DynBuffer: DynResource + std::fmt::Debug {} pub trait DynComputePipeline: DynResource + std::fmt::Debug {} +pub trait DynFence: DynResource + std::fmt::Debug {} +pub trait DynPipelineCache: DynResource + std::fmt::Debug {} pub trait DynPipelineLayout: DynResource + std::fmt::Debug {} pub trait DynQuerySet: DynResource + std::fmt::Debug {} pub trait DynRenderPipeline: DynResource + std::fmt::Debug {} +pub trait DynSampler: DynResource + std::fmt::Debug {} +pub trait DynShaderModule: DynResource + std::fmt::Debug {} pub trait DynTexture: DynResource + std::fmt::Debug {} pub trait DynTextureView: DynResource + std::fmt::Debug {} diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 2b628b2bc1..67e24a70e9 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -266,8 +266,9 @@ mod dynamic; pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ - DynBindGroup, DynBuffer, DynCommandEncoder, DynComputePipeline, DynDevice, DynPipelineLayout, - DynQuerySet, DynRenderPipeline, DynResource, DynTexture, DynTextureView, + DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandEncoder, + DynComputePipeline, DynDevice, DynFence, DynPipelineCache, DynPipelineLayout, DynQuerySet, + DynRenderPipeline, DynResource, DynSampler, DynShaderModule, DynTexture, DynTextureView, }; use std::{ From b662e7108914878c827a33cc5fd5029926c628c7 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 20 Jul 2024 21:14:48 +0200 Subject: [PATCH 18/53] impl DynShaderModule for all backends --- wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 3dbb58abb0..8f2e57d6e7 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -608,6 +608,8 @@ pub struct ShaderModule { raw_name: Option, } +impl crate::DynShaderModule for ShaderModule {} + pub(super) enum CompiledShader { #[allow(unused)] Dxc(Vec), diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index d39d41adca..068874948c 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -48,6 +48,7 @@ impl crate::DynComputePipeline for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} +impl crate::DynShaderModule for Resource {} impl crate::DynTexture for Resource {} impl crate::DynTextureView for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 5709735202..433ff48f08 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -542,6 +542,8 @@ pub struct ShaderModule { id: ShaderId, } +impl crate::DynShaderModule for ShaderModule {} + #[derive(Clone, Debug, Default)] struct VertexFormatDesc { element_count: i32, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 67e24a70e9..1716357c2b 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -437,7 +437,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type BindGroupLayout: fmt::Debug + WasmNotSendSync; type BindGroup: DynBindGroup; type PipelineLayout: DynPipelineLayout; - type ShaderModule: fmt::Debug + WasmNotSendSync; + type ShaderModule: DynShaderModule; type RenderPipeline: DynRenderPipeline; type ComputePipeline: DynComputePipeline; type PipelineCache: fmt::Debug + WasmNotSendSync; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index a7282ca4cd..d8d9b3fcb6 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -714,6 +714,8 @@ pub struct ShaderModule { runtime_checks: bool, } +impl crate::DynShaderModule for ShaderModule {} + #[derive(Debug, Default)] struct PipelineStageInfo { push_constants: Option, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 2d4a971739..8d007b9f70 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -821,6 +821,8 @@ pub enum ShaderModule { }, } +impl crate::DynShaderModule for ShaderModule {} + #[derive(Debug)] pub struct RenderPipeline { raw: vk::Pipeline, From e9860f75d0fc5813f2508e39944f36a9c68eff4c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 11:18:31 +0200 Subject: [PATCH 19/53] impl DynCommandBuffer --- wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/dynamic/mod.rs | 1 + wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 9 +++++---- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 8f2e57d6e7..4519e5bc3e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -413,6 +413,8 @@ pub struct CommandBuffer { raw: d3d12::GraphicsCommandList, } +impl crate::DynCommandBuffer for CommandBuffer {} + unsafe impl Send for CommandBuffer {} unsafe impl Sync for CommandBuffer {} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index cb114af9f1..0262d4fbb1 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -92,6 +92,7 @@ pub trait DynAccelerationStructure: DynResource + std::fmt::Debug {} pub trait DynBindGroup: DynResource + std::fmt::Debug {} pub trait DynBindGroupLayout: DynResource + std::fmt::Debug {} pub trait DynBuffer: DynResource + std::fmt::Debug {} +pub trait DynCommandBuffer: DynResource + std::fmt::Debug {} pub trait DynComputePipeline: DynResource + std::fmt::Debug {} pub trait DynFence: DynResource + std::fmt::Debug {} pub trait DynPipelineCache: DynResource + std::fmt::Debug {} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 068874948c..6dbe60c767 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -44,6 +44,7 @@ crate::impl_dyn_resource!(Context, Encoder, Resource); impl crate::DynBindGroup for Resource {} impl crate::DynBuffer for Resource {} +impl crate::DynCommandBuffer for Resource {} impl crate::DynComputePipeline for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 433ff48f08..93b7ba92f4 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -988,6 +988,8 @@ pub struct CommandBuffer { queries: Vec, } +impl crate::DynCommandBuffer for CommandBuffer {} + impl fmt::Debug for CommandBuffer { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut builder = f.debug_struct("CommandBuffer"); diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 1716357c2b..91883e3421 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -266,9 +266,10 @@ mod dynamic; pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ - DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandEncoder, - DynComputePipeline, DynDevice, DynFence, DynPipelineCache, DynPipelineLayout, DynQuerySet, - DynRenderPipeline, DynResource, DynSampler, DynShaderModule, DynTexture, DynTextureView, + DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandBuffer, + DynCommandEncoder, DynComputePipeline, DynDevice, DynFence, DynPipelineCache, + DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynSampler, DynShaderModule, + DynTexture, DynTextureView, }; use std::{ @@ -406,7 +407,7 @@ pub trait Api: Clone + fmt::Debug + Sized { /// them to [`CommandEncoder::reset_all`]. /// /// [`CommandEncoder`]: Api::CommandEncoder - type CommandBuffer: WasmNotSendSync + fmt::Debug; + type CommandBuffer: DynCommandBuffer + fmt::Debug; type Buffer: DynBuffer; type Texture: DynTexture; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index d8d9b3fcb6..6ed68e9121 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -907,6 +907,8 @@ pub struct CommandBuffer { raw: metal::CommandBuffer, } +impl crate::DynCommandBuffer for CommandBuffer {} + unsafe impl Send for CommandBuffer {} unsafe impl Sync for CommandBuffer {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 8d007b9f70..1b22a9628b 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -811,6 +811,8 @@ pub struct CommandBuffer { raw: vk::CommandBuffer, } +impl crate::DynCommandBuffer for CommandBuffer {} + #[derive(Debug)] #[allow(clippy::large_enum_variant)] pub enum ShaderModule { From 8595a1cabd6ff0bd423914414969d888502d0486 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 11:51:45 +0200 Subject: [PATCH 20/53] Device now has to implement DynResource --- wgpu-hal/src/dx12/mod.rs | 1 + wgpu-hal/src/dynamic/device.rs | 6 +++--- wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/mod.rs | 1 + wgpu-hal/src/vulkan/mod.rs | 1 + 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 4519e5bc3e..ec8e79e822 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -94,6 +94,7 @@ crate::impl_dyn_resource!( CommandBuffer, CommandEncoder, ComputePipeline, + Device, Fence, PipelineCache, PipelineLayout, diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 30e245867c..b92139d417 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -1,12 +1,12 @@ -use crate::{Device, DynBuffer}; +use crate::{Device, DynBuffer, DynResource}; use super::DynResourceExt; -pub trait DynDevice { +pub trait DynDevice: DynResource { unsafe fn destroy_buffer(&self, buffer: Box); } -impl DynDevice for D { +impl DynDevice for D { unsafe fn destroy_buffer(&self, buffer: Box) { unsafe { D::destroy_buffer(self, buffer.unbox()) }; } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 93b7ba92f4..c1abe2d2c0 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -171,6 +171,7 @@ crate::impl_dyn_resource!( CommandBuffer, CommandEncoder, ComputePipeline, + Device, Fence, PipelineLayout, QuerySet, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 91883e3421..6dbff8db78 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -394,7 +394,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type Instance: Instance; type Surface: Surface; type Adapter: Adapter; - type Device: Device; + type Device: DynDevice + Device; type Queue: Queue; type CommandEncoder: DynCommandEncoder + CommandEncoder; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 6ed68e9121..4263e0d488 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -78,6 +78,7 @@ crate::impl_dyn_resource!( CommandBuffer, CommandEncoder, ComputePipeline, + Device, Fence, PipelineLayout, QuerySet, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 1b22a9628b..5ba81a17ae 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -85,6 +85,7 @@ crate::impl_dyn_resource!( CommandBuffer, CommandEncoder, ComputePipeline, + Device, Fence, PipelineCache, PipelineLayout, From e4744df564a869874599c2a66cab5828e2409611 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 11:59:03 +0200 Subject: [PATCH 21/53] impl DynFence for all fences --- wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index ec8e79e822..8267f7f4bf 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -525,6 +525,8 @@ pub struct Fence { raw: d3d12::Fence, } +impl crate::DynFence for Fence {} + unsafe impl Send for Fence {} unsafe impl Sync for Fence {} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 6dbe60c767..0e7f43073b 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -46,6 +46,7 @@ impl crate::DynBindGroup for Resource {} impl crate::DynBuffer for Resource {} impl crate::DynCommandBuffer for Resource {} impl crate::DynComputePipeline for Resource {} +impl crate::DynFence for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index c1abe2d2c0..412424a851 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -693,6 +693,8 @@ pub struct Fence { pending: Vec<(crate::FenceValue, glow::Fence)>, } +impl crate::DynFence for Fence {} + #[cfg(any( not(target_arch = "wasm32"), all( diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 6dbff8db78..6ae5d6bdc7 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -433,7 +433,7 @@ pub trait Api: Clone + fmt::Debug + Sized { /// before a lower-valued operation, then waiting for the fence to reach the /// lower value could return before the lower-valued operation has actually /// finished. - type Fence: fmt::Debug + WasmNotSendSync; + type Fence: DynFence + fmt::Debug; type BindGroupLayout: fmt::Debug + WasmNotSendSync; type BindGroup: DynBindGroup; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 4263e0d488..fdcf6550b6 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -811,6 +811,8 @@ pub struct Fence { pending_command_buffers: Vec<(crate::FenceValue, metal::CommandBuffer)>, } +impl crate::DynFence for Fence {} + unsafe impl Send for Fence {} unsafe impl Sync for Fence {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 5ba81a17ae..360abdfee6 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -901,6 +901,8 @@ pub enum Fence { }, } +impl crate::DynFence for Fence {} + impl Fence { /// Return the highest [`FenceValue`] among the signalled fences in `active`. /// From d94e4659d7c8381f2d5bf49b8e7a3e915e7eaf46 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 12:04:44 +0200 Subject: [PATCH 22/53] impl DynSurfaceTexture for all surface textures --- wgpu-hal/src/dx12/mod.rs | 1 + wgpu-hal/src/dynamic/mod.rs | 1 + wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 4 ++-- wgpu-hal/src/metal/mod.rs | 3 +++ wgpu-hal/src/vulkan/mod.rs | 3 +++ 7 files changed, 12 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 8267f7f4bf..44a56a244e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -456,6 +456,7 @@ pub struct Texture { } impl crate::DynTexture for Texture {} +impl crate::DynSurfaceTexture for Texture {} unsafe impl Send for Texture {} unsafe impl Sync for Texture {} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 0262d4fbb1..a7e343ad49 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -101,6 +101,7 @@ pub trait DynQuerySet: DynResource + std::fmt::Debug {} pub trait DynRenderPipeline: DynResource + std::fmt::Debug {} pub trait DynSampler: DynResource + std::fmt::Debug {} pub trait DynShaderModule: DynResource + std::fmt::Debug {} +pub trait DynSurfaceTexture: DynResource + std::fmt::Debug {} pub trait DynTexture: DynResource + std::fmt::Debug {} pub trait DynTextureView: DynResource + std::fmt::Debug {} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 0e7f43073b..37723326bc 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -51,6 +51,7 @@ impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} impl crate::DynShaderModule for Resource {} +impl crate::DynSurfaceTexture for Resource {} impl crate::DynTexture for Resource {} impl crate::DynTextureView for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 412424a851..2e76871b1d 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -375,6 +375,7 @@ pub struct Texture { } impl crate::DynTexture for Texture {} +impl crate::DynSurfaceTexture for Texture {} impl Texture { pub fn default_framebuffer(format: wgt::TextureFormat) -> Self { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 6ae5d6bdc7..9a80eea6c3 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -269,7 +269,7 @@ pub use dynamic::{ DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandBuffer, DynCommandEncoder, DynComputePipeline, DynDevice, DynFence, DynPipelineCache, DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynSampler, DynShaderModule, - DynTexture, DynTextureView, + DynSurfaceTexture, DynTexture, DynTextureView, }; use std::{ @@ -411,7 +411,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type Buffer: DynBuffer; type Texture: DynTexture; - type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow; + type SurfaceTexture: DynSurfaceTexture + fmt::Debug + Borrow; type TextureView: DynTextureView; type Sampler: fmt::Debug + WasmNotSendSync; type QuerySet: DynQuerySet; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index fdcf6550b6..35a4d8159a 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -86,6 +86,7 @@ crate::impl_dyn_resource!( Sampler, ShaderModule, Surface, + SurfaceTexture, Texture, TextureView ); @@ -381,6 +382,8 @@ pub struct SurfaceTexture { present_with_transaction: bool, } +impl crate::DynSurfaceTexture for SurfaceTexture {} + impl std::borrow::Borrow for SurfaceTexture { fn borrow(&self) -> &Texture { &self.texture diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 360abdfee6..f0fb84f153 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -94,6 +94,7 @@ crate::impl_dyn_resource!( Sampler, ShaderModule, Surface, + SurfaceTexture, Texture, TextureView ); @@ -377,6 +378,8 @@ pub struct SurfaceTexture { surface_semaphores: Arc>, } +impl crate::DynSurfaceTexture for SurfaceTexture {} + impl Borrow for SurfaceTexture { fn borrow(&self) -> &Texture { &self.texture From 39b214abf322accc4aa5a9168cc78581be8514d0 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 12:13:23 +0200 Subject: [PATCH 23/53] introduce DynSurface --- wgpu-hal/src/dynamic/mod.rs | 6 ++- wgpu-hal/src/dynamic/surface.rs | 71 +++++++++++++++++++++++++++++++++ wgpu-hal/src/lib.rs | 8 ++-- 3 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 wgpu-hal/src/dynamic/surface.rs diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index a7e343ad49..f51bf742c7 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -1,8 +1,10 @@ mod command; mod device; +mod surface; -pub use self::command::DynCommandEncoder; -pub use self::device::DynDevice; +pub use command::DynCommandEncoder; +pub use device::DynDevice; +pub use surface::{DynAcquiredSurfaceTexture, DynSurface}; use std::any::Any; diff --git a/wgpu-hal/src/dynamic/surface.rs b/wgpu-hal/src/dynamic/surface.rs new file mode 100644 index 0000000000..d6c3dad623 --- /dev/null +++ b/wgpu-hal/src/dynamic/surface.rs @@ -0,0 +1,71 @@ +use crate::{ + DynDevice, DynFence, DynResource, DynSurfaceTexture, Surface, SurfaceConfiguration, + SurfaceError, +}; + +use super::DynResourceExt as _; + +#[derive(Debug)] +pub struct DynAcquiredSurfaceTexture { + pub texture: Box, + /// The presentation configuration no longer matches + /// the surface properties exactly, but can still be used to present + /// to the surface successfully. + pub suboptimal: bool, +} + +pub trait DynSurface: DynResource { + unsafe fn configure( + &self, + device: &dyn DynDevice, + config: &SurfaceConfiguration, + ) -> Result<(), SurfaceError>; + + unsafe fn unconfigure(&self, device: &dyn DynDevice); + + unsafe fn acquire_texture( + &self, + timeout: Option, + fence: &dyn DynFence, + ) -> Result, SurfaceError>; + + unsafe fn discard_texture(&self, texture: Box); +} + +impl DynSurface for S { + unsafe fn configure( + &self, + device: &dyn DynDevice, + config: &SurfaceConfiguration, + ) -> Result<(), SurfaceError> { + let device = device.expect_downcast_ref(); + unsafe { S::configure(self, device, config) } + } + + unsafe fn unconfigure(&self, device: &dyn DynDevice) { + let device = device.expect_downcast_ref(); + unsafe { S::unconfigure(self, device) } + } + + unsafe fn acquire_texture( + &self, + timeout: Option, + fence: &dyn DynFence, + ) -> Result, SurfaceError> { + let fence = fence.expect_downcast_ref(); + unsafe { S::acquire_texture(self, timeout, fence) }.map(|acquired| { + acquired.map(|ast| { + let texture = Box::new(ast.texture); + let suboptimal = ast.suboptimal; + DynAcquiredSurfaceTexture { + texture, + suboptimal, + } + }) + }) + } + + unsafe fn discard_texture(&self, texture: Box) { + unsafe { S::discard_texture(self, texture.unbox()) } + } +} diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 9a80eea6c3..c97c232a6c 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -266,10 +266,10 @@ mod dynamic; pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ - DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandBuffer, - DynCommandEncoder, DynComputePipeline, DynDevice, DynFence, DynPipelineCache, - DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynSampler, DynShaderModule, - DynSurfaceTexture, DynTexture, DynTextureView, + DynAccelerationStructure, DynAcquiredSurfaceTexture, DynBindGroup, DynBindGroupLayout, + DynBuffer, DynCommandBuffer, DynCommandEncoder, DynComputePipeline, DynDevice, DynFence, + DynPipelineCache, DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynSampler, + DynShaderModule, DynSurface, DynSurfaceTexture, DynTexture, DynTextureView, }; use std::{ From 24bd6e09b8c2f30f72ae982b1217aa7830cc3186 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 12:19:47 +0200 Subject: [PATCH 24/53] introduce DynQueue --- wgpu-hal/src/dx12/mod.rs | 6 ++++ wgpu-hal/src/dynamic/mod.rs | 7 ++++- wgpu-hal/src/dynamic/queue.rs | 54 +++++++++++++++++++++++++++++++++++ wgpu-hal/src/empty.rs | 6 ++++ wgpu-hal/src/gles/mod.rs | 6 ++++ wgpu-hal/src/lib.rs | 6 ++-- wgpu-hal/src/metal/mod.rs | 6 ++++ wgpu-hal/src/vulkan/mod.rs | 6 ++++ 8 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 wgpu-hal/src/dynamic/queue.rs diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 44a56a244e..345624da64 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -458,6 +458,12 @@ pub struct Texture { impl crate::DynTexture for Texture {} impl crate::DynSurfaceTexture for Texture {} +impl std::borrow::Borrow for Texture { + fn borrow(&self) -> &dyn crate::DynTexture { + self + } +} + unsafe impl Send for Texture {} unsafe impl Sync for Texture {} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index f51bf742c7..2607ba44c3 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -1,9 +1,11 @@ mod command; mod device; +mod queue; mod surface; pub use command::DynCommandEncoder; pub use device::DynDevice; +pub use queue::DynQueue; pub use surface::{DynAcquiredSurfaceTexture, DynSurface}; use std::any::Any; @@ -103,7 +105,10 @@ pub trait DynQuerySet: DynResource + std::fmt::Debug {} pub trait DynRenderPipeline: DynResource + std::fmt::Debug {} pub trait DynSampler: DynResource + std::fmt::Debug {} pub trait DynShaderModule: DynResource + std::fmt::Debug {} -pub trait DynSurfaceTexture: DynResource + std::fmt::Debug {} +pub trait DynSurfaceTexture: + DynResource + std::borrow::Borrow + std::fmt::Debug +{ +} pub trait DynTexture: DynResource + std::fmt::Debug {} pub trait DynTextureView: DynResource + std::fmt::Debug {} diff --git a/wgpu-hal/src/dynamic/queue.rs b/wgpu-hal/src/dynamic/queue.rs new file mode 100644 index 0000000000..14d7e5a969 --- /dev/null +++ b/wgpu-hal/src/dynamic/queue.rs @@ -0,0 +1,54 @@ +use crate::{ + DeviceError, DynCommandBuffer, DynFence, DynResource, DynSurface, DynSurfaceTexture, + FenceValue, Queue, SurfaceError, +}; + +use super::DynResourceExt as _; + +pub trait DynQueue: DynResource { + unsafe fn submit( + &self, + command_buffers: &[&dyn DynCommandBuffer], + surface_textures: &[&dyn DynSurfaceTexture], + signal_fence: (&mut dyn DynFence, FenceValue), + ) -> Result<(), DeviceError>; + unsafe fn present( + &self, + surface: &dyn DynSurface, + texture: Box, + ) -> Result<(), SurfaceError>; + unsafe fn get_timestamp_period(&self) -> f32; +} + +impl DynQueue for Q { + unsafe fn submit( + &self, + command_buffers: &[&dyn DynCommandBuffer], + surface_textures: &[&dyn DynSurfaceTexture], + signal_fence: (&mut dyn DynFence, FenceValue), + ) -> Result<(), DeviceError> { + let command_buffers = command_buffers + .iter() + .map(|cb| (*cb).expect_downcast_ref()) + .collect::>(); + let surface_textures = surface_textures + .iter() + .map(|surface| (*surface).expect_downcast_ref()) + .collect::>(); + let signal_fence = (signal_fence.0.expect_downcast_mut(), signal_fence.1); + unsafe { Q::submit(self, &command_buffers, &surface_textures, signal_fence) } + } + + unsafe fn present( + &self, + surface: &dyn DynSurface, + texture: Box, + ) -> Result<(), SurfaceError> { + let surface = surface.expect_downcast_ref(); + unsafe { Q::present(self, surface, texture.unbox()) } + } + + unsafe fn get_timestamp_period(&self) -> f32 { + unsafe { Q::get_timestamp_period(self) } + } +} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 37723326bc..9b97b16b80 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -55,6 +55,12 @@ impl crate::DynSurfaceTexture for Resource {} impl crate::DynTexture for Resource {} impl crate::DynTextureView for Resource {} +impl std::borrow::Borrow for Resource { + fn borrow(&self) -> &dyn crate::DynTexture { + self + } +} + impl crate::Instance for Context { type A = Api; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 2e76871b1d..7208f5c7e4 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -377,6 +377,12 @@ pub struct Texture { impl crate::DynTexture for Texture {} impl crate::DynSurfaceTexture for Texture {} +impl std::borrow::Borrow for Texture { + fn borrow(&self) -> &dyn crate::DynTexture { + self + } +} + impl Texture { pub fn default_framebuffer(format: wgt::TextureFormat) -> Self { Self { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index c97c232a6c..c7939066c2 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -268,8 +268,8 @@ pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ DynAccelerationStructure, DynAcquiredSurfaceTexture, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandBuffer, DynCommandEncoder, DynComputePipeline, DynDevice, DynFence, - DynPipelineCache, DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynSampler, - DynShaderModule, DynSurface, DynSurfaceTexture, DynTexture, DynTextureView, + DynPipelineCache, DynPipelineLayout, DynQuerySet, DynQueue, DynRenderPipeline, DynResource, + DynSampler, DynShaderModule, DynSurface, DynSurfaceTexture, DynTexture, DynTextureView, }; use std::{ @@ -392,7 +392,7 @@ impl InstanceError { pub trait Api: Clone + fmt::Debug + Sized { type Instance: Instance; - type Surface: Surface; + type Surface: DynSurface + Surface; type Adapter: Adapter; type Device: DynDevice + Device; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 35a4d8159a..322e627597 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -390,6 +390,12 @@ impl std::borrow::Borrow for SurfaceTexture { } } +impl std::borrow::Borrow for SurfaceTexture { + fn borrow(&self) -> &dyn crate::DynTexture { + &self.texture + } +} + unsafe impl Send for SurfaceTexture {} unsafe impl Sync for SurfaceTexture {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index f0fb84f153..d8692d7205 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -386,6 +386,12 @@ impl Borrow for SurfaceTexture { } } +impl Borrow for SurfaceTexture { + fn borrow(&self) -> &dyn crate::DynTexture { + &self.texture + } +} + pub struct Adapter { raw: vk::PhysicalDevice, instance: Arc, From d6856602ec861b9c6ae8ffbedd30f5650eef5453 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 21 Jul 2024 12:52:25 +0200 Subject: [PATCH 25/53] DynDevice buffer operations --- wgpu-hal/src/dynamic/device.rs | 53 ++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index b92139d417..65944acb54 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -1,13 +1,62 @@ -use crate::{Device, DynBuffer, DynResource}; +use crate::{ + BufferDescriptor, BufferMapping, Device, DeviceError, DynBuffer, DynResource, MemoryRange, +}; -use super::DynResourceExt; +use super::DynResourceExt as _; pub trait DynDevice: DynResource { + unsafe fn create_buffer( + &self, + desc: &BufferDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_buffer(&self, buffer: Box); + + unsafe fn map_buffer( + &self, + buffer: &dyn DynBuffer, + range: MemoryRange, + ) -> Result; + + unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer); + + unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]); + unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]); } impl DynDevice for D { + unsafe fn create_buffer( + &self, + desc: &BufferDescriptor, + ) -> Result, DeviceError> { + unsafe { D::create_buffer(self, desc) }.map(|b| -> Box { Box::new(b) }) + } + unsafe fn destroy_buffer(&self, buffer: Box) { unsafe { D::destroy_buffer(self, buffer.unbox()) }; } + + unsafe fn map_buffer( + &self, + buffer: &dyn DynBuffer, + range: MemoryRange, + ) -> Result { + let buffer = buffer.expect_downcast_ref(); + unsafe { D::map_buffer(self, buffer, range) } + } + + unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer) { + let buffer = buffer.expect_downcast_ref(); + unsafe { D::unmap_buffer(self, buffer) } + } + + unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) { + let buffer = buffer.expect_downcast_ref(); + unsafe { D::flush_mapped_ranges(self, buffer, ranges.iter().cloned()) } + } + + unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) { + let buffer = buffer.expect_downcast_ref(); + unsafe { D::invalidate_mapped_ranges(self, buffer, ranges.iter().cloned()) } + } } From 9dd24e0678bd49977ae3855a1c38dcad96452565 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 24 Jul 2024 23:51:24 +0200 Subject: [PATCH 26/53] DynDevice create/destroy for texture/textureview/sampler --- wgpu-hal/src/dx12/mod.rs | 2 + wgpu-hal/src/dynamic/device.rs | 69 +++++++++++++++++++++++++++++++++- wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 + wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/mod.rs | 2 + wgpu-hal/src/vulkan/mod.rs | 2 + 7 files changed, 77 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 345624da64..a0aadb795f 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -513,6 +513,8 @@ pub struct Sampler { handle: descriptor::Handle, } +impl crate::DynSampler for Sampler {} + unsafe impl Send for Sampler {} unsafe impl Sync for Sampler {} diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 65944acb54..75de0413ac 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -1,8 +1,9 @@ use crate::{ - BufferDescriptor, BufferMapping, Device, DeviceError, DynBuffer, DynResource, MemoryRange, + Api, BufferDescriptor, BufferMapping, Device, DeviceError, DynBuffer, DynResource, MemoryRange, + SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, }; -use super::DynResourceExt as _; +use super::{DynResourceExt as _, DynSampler, DynTexture, DynTextureView}; pub trait DynDevice: DynResource { unsafe fn create_buffer( @@ -22,6 +23,23 @@ pub trait DynDevice: DynResource { unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]); unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]); + + unsafe fn create_texture( + &self, + desc: &TextureDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_texture(&self, texture: Box); + unsafe fn create_texture_view( + &self, + texture: &dyn DynTexture, + desc: &TextureViewDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_texture_view(&self, view: Box); + unsafe fn create_sampler( + &self, + desc: &SamplerDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_sampler(&self, sampler: Box); } impl DynDevice for D { @@ -59,4 +77,51 @@ impl DynDevice for D { let buffer = buffer.expect_downcast_ref(); unsafe { D::invalidate_mapped_ranges(self, buffer, ranges.iter().cloned()) } } + + unsafe fn create_texture( + &self, + desc: &TextureDescriptor, + ) -> Result, DeviceError> { + unsafe { D::create_texture(self, desc) }.map(|b| { + let boxed_texture: Box<::Texture> = Box::new(b); + let boxed_texture: Box = boxed_texture; + boxed_texture + }) + } + + unsafe fn destroy_texture(&self, texture: Box) { + unsafe { D::destroy_texture(self, texture.unbox()) }; + } + + unsafe fn create_texture_view( + &self, + texture: &dyn DynTexture, + desc: &TextureViewDescriptor, + ) -> Result, DeviceError> { + let texture = texture.expect_downcast_ref(); + unsafe { D::create_texture_view(self, texture, desc) }.map(|b| { + let boxed_texture_view: Box<::TextureView> = Box::new(b); + let boxed_texture_view: Box = boxed_texture_view; + boxed_texture_view + }) + } + + unsafe fn destroy_texture_view(&self, view: Box) { + unsafe { D::destroy_texture_view(self, view.unbox()) }; + } + + unsafe fn create_sampler( + &self, + desc: &SamplerDescriptor, + ) -> Result, DeviceError> { + unsafe { D::create_sampler(self, desc) }.map(|b| { + let boxed_sampler: Box<::Sampler> = Box::new(b); + let boxed_sampler: Box = boxed_sampler; + boxed_sampler + }) + } + + unsafe fn destroy_sampler(&self, sampler: Box) { + unsafe { D::destroy_sampler(self, sampler.unbox()) }; + } } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 9b97b16b80..e800324024 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -50,6 +50,7 @@ impl crate::DynFence for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} +impl crate::DynSampler for Resource {} impl crate::DynShaderModule for Resource {} impl crate::DynSurfaceTexture for Resource {} impl crate::DynTexture for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 7208f5c7e4..26693d8e60 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -477,6 +477,8 @@ pub struct Sampler { raw: glow::Sampler, } +impl crate::DynSampler for Sampler {} + #[derive(Debug)] pub struct BindGroupLayout { entries: Arc<[wgt::BindGroupLayoutEntry]>, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index c7939066c2..d41137ad1a 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -413,7 +413,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type Texture: DynTexture; type SurfaceTexture: DynSurfaceTexture + fmt::Debug + Borrow; type TextureView: DynTextureView; - type Sampler: fmt::Debug + WasmNotSendSync; + type Sampler: DynSampler + fmt::Debug; type QuerySet: DynQuerySet; /// A value you can block on to wait for something to finish. diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 322e627597..e353f85a0d 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -542,6 +542,8 @@ pub struct Sampler { raw: metal::SamplerState, } +impl crate::DynSampler for Sampler {} + unsafe impl Send for Sampler {} unsafe impl Sync for Sampler {} diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index d8692d7205..1898e59539 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -715,6 +715,8 @@ pub struct Sampler { raw: vk::Sampler, } +impl crate::DynSampler for Sampler {} + #[derive(Debug)] pub struct BindGroupLayout { raw: vk::DescriptorSetLayout, From 3217d4341f7d983dd0ae24cbb46d4e10a0057020 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 27 Jul 2024 12:30:59 +0200 Subject: [PATCH 27/53] DynDevice create/destroy command encoder --- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 1 + wgpu-hal/src/dynamic/device.rs | 33 ++++++++++++++++++++++++++++++--- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/device.rs | 2 +- wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 8 ++++---- wgpu-hal/src/metal/device.rs | 2 +- wgpu-hal/src/metal/mod.rs | 1 + wgpu-hal/src/vulkan/device.rs | 2 +- wgpu-hal/src/vulkan/mod.rs | 1 + 11 files changed, 43 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index b3204a8cc0..b74c9ebca2 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -689,7 +689,7 @@ impl crate::Device for super::Device { unsafe fn create_command_encoder( &self, - desc: &crate::CommandEncoderDescriptor, + desc: &crate::CommandEncoderDescriptor, ) -> Result { let allocator = self .raw diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index a0aadb795f..addb2a32ec 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -99,6 +99,7 @@ crate::impl_dyn_resource!( PipelineCache, PipelineLayout, QuerySet, + Queue, RenderPipeline, Sampler, ShaderModule, diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 75de0413ac..de6c93b8bb 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -1,9 +1,14 @@ +// Box casts are needed, alternative would be a temporaries which are more verbose and not more expressive. +#![allow(trivial_casts)] + use crate::{ - Api, BufferDescriptor, BufferMapping, Device, DeviceError, DynBuffer, DynResource, MemoryRange, - SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, + Api, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, Device, DeviceError, DynBuffer, + DynResource, MemoryRange, SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, }; -use super::{DynResourceExt as _, DynSampler, DynTexture, DynTextureView}; +use super::{ + DynCommandEncoder, DynQueue, DynResourceExt as _, DynSampler, DynTexture, DynTextureView, +}; pub trait DynDevice: DynResource { unsafe fn create_buffer( @@ -40,6 +45,12 @@ pub trait DynDevice: DynResource { desc: &SamplerDescriptor, ) -> Result, DeviceError>; unsafe fn destroy_sampler(&self, sampler: Box); + + unsafe fn create_command_encoder( + &self, + desc: &CommandEncoderDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_command_encoder(&self, pool: Box); } impl DynDevice for D { @@ -124,4 +135,20 @@ impl DynDevice for D { unsafe fn destroy_sampler(&self, sampler: Box) { unsafe { D::destroy_sampler(self, sampler.unbox()) }; } + + unsafe fn create_command_encoder( + &self, + desc: &CommandEncoderDescriptor<'_, dyn DynQueue>, + ) -> Result, DeviceError> { + let desc = CommandEncoderDescriptor { + label: desc.label, + queue: desc.queue.expect_downcast_ref(), + }; + unsafe { D::create_command_encoder(self, &desc) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_command_encoder(&self, encoder: Box) { + unsafe { D::destroy_command_encoder(self, encoder.unbox()) }; + } } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index e800324024..f33dc7b4b0 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -195,7 +195,7 @@ impl crate::Device for Context { unsafe fn create_command_encoder( &self, - desc: &crate::CommandEncoderDescriptor, + desc: &crate::CommandEncoderDescriptor, ) -> DeviceResult { Ok(Encoder) } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index c651da6828..6ce15269b0 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1109,7 +1109,7 @@ impl crate::Device for super::Device { unsafe fn create_command_encoder( &self, - _desc: &crate::CommandEncoderDescriptor, + _desc: &crate::CommandEncoderDescriptor, ) -> Result { self.counters.command_encoders.add(1); diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 26693d8e60..2306e6ea3f 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -175,6 +175,7 @@ crate::impl_dyn_resource!( Fence, PipelineLayout, QuerySet, + Queue, RenderPipeline, Sampler, ShaderModule, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index d41137ad1a..0c83739d82 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -396,7 +396,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type Adapter: Adapter; type Device: DynDevice + Device; - type Queue: Queue; + type Queue: DynQueue + Queue; type CommandEncoder: DynCommandEncoder + CommandEncoder; /// This API's command buffer type. @@ -789,7 +789,7 @@ pub trait Device: WasmNotSendSync { /// The new `CommandEncoder` is in the "closed" state. unsafe fn create_command_encoder( &self, - desc: &CommandEncoderDescriptor, + desc: &CommandEncoderDescriptor<::Queue>, ) -> Result<::CommandEncoder, DeviceError>; unsafe fn destroy_command_encoder(&self, pool: ::CommandEncoder); @@ -1831,9 +1831,9 @@ pub struct BindGroupDescriptor<'a, A: Api> { } #[derive(Clone, Debug)] -pub struct CommandEncoderDescriptor<'a, A: Api> { +pub struct CommandEncoderDescriptor<'a, Q: DynQueue + ?Sized> { pub label: Label<'a>, - pub queue: &'a A::Queue, + pub queue: &'a Q, } /// Naga shader module. diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 4ca392bc1f..77631ab937 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -569,7 +569,7 @@ impl crate::Device for super::Device { unsafe fn create_command_encoder( &self, - desc: &crate::CommandEncoderDescriptor, + desc: &crate::CommandEncoderDescriptor, ) -> Result { self.counters.command_encoders.add(1); Ok(super::CommandEncoder { diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index e353f85a0d..5c836afd94 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -82,6 +82,7 @@ crate::impl_dyn_resource!( Fence, PipelineLayout, QuerySet, + Queue, RenderPipeline, Sampler, ShaderModule, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index a71263df50..9e9c50171f 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1215,7 +1215,7 @@ impl crate::Device for super::Device { unsafe fn create_command_encoder( &self, - desc: &crate::CommandEncoderDescriptor, + desc: &crate::CommandEncoderDescriptor, ) -> Result { let vk_info = vk::CommandPoolCreateInfo::default() .queue_family_index(desc.queue.family_index) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 1898e59539..3f1ba28bc7 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -90,6 +90,7 @@ crate::impl_dyn_resource!( PipelineCache, PipelineLayout, QuerySet, + Queue, RenderPipeline, Sampler, ShaderModule, From 38c90316254336dad7b01d3860621138022657a6 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 27 Jul 2024 12:35:22 +0200 Subject: [PATCH 28/53] DynDevice create/destroy bind group layout --- wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/dynamic/device.rs | 26 +++++++++++++++++++++++--- wgpu-hal/src/empty.rs | 1 + wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index addb2a32ec..fb0d9a1997 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -555,6 +555,8 @@ pub struct BindGroupLayout { copy_counts: Vec, // all 1's } +impl crate::DynBindGroupLayout for BindGroupLayout {} + #[derive(Debug, Clone, Copy)] enum BufferViewKind { Constant, diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index de6c93b8bb..a9adc36227 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -2,12 +2,14 @@ #![allow(trivial_casts)] use crate::{ - Api, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, Device, DeviceError, DynBuffer, - DynResource, MemoryRange, SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, + Api, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, + Device, DeviceError, DynBuffer, DynResource, MemoryRange, SamplerDescriptor, TextureDescriptor, + TextureViewDescriptor, }; use super::{ - DynCommandEncoder, DynQueue, DynResourceExt as _, DynSampler, DynTexture, DynTextureView, + DynBindGroupLayout, DynCommandEncoder, DynQueue, DynResourceExt as _, DynSampler, DynTexture, + DynTextureView, }; pub trait DynDevice: DynResource { @@ -51,6 +53,12 @@ pub trait DynDevice: DynResource { desc: &CommandEncoderDescriptor, ) -> Result, DeviceError>; unsafe fn destroy_command_encoder(&self, pool: Box); + + unsafe fn create_bind_group_layout( + &self, + desc: &BindGroupLayoutDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_bind_group_layout(&self, bg_layout: Box); } impl DynDevice for D { @@ -151,4 +159,16 @@ impl DynDevice for D { unsafe fn destroy_command_encoder(&self, encoder: Box) { unsafe { D::destroy_command_encoder(self, encoder.unbox()) }; } + + unsafe fn create_bind_group_layout( + &self, + desc: &BindGroupLayoutDescriptor, + ) -> Result, DeviceError> { + unsafe { D::create_bind_group_layout(self, desc) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_bind_group_layout(&self, bg_layout: Box) { + unsafe { D::destroy_bind_group_layout(self, bg_layout.unbox()) }; + } } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index f33dc7b4b0..b1d0eed6c4 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -43,6 +43,7 @@ impl crate::Api for Api { crate::impl_dyn_resource!(Context, Encoder, Resource); impl crate::DynBindGroup for Resource {} +impl crate::DynBindGroupLayout for Resource {} impl crate::DynBuffer for Resource {} impl crate::DynCommandBuffer for Resource {} impl crate::DynComputePipeline for Resource {} diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 2306e6ea3f..9fd40d4d26 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -485,6 +485,8 @@ pub struct BindGroupLayout { entries: Arc<[wgt::BindGroupLayoutEntry]>, } +impl crate::DynBindGroupLayout for BindGroupLayout {} + #[derive(Debug)] struct BindGroupLayoutInfo { entries: Arc<[wgt::BindGroupLayoutEntry]>, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 0c83739d82..26f4918fbf 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -435,7 +435,7 @@ pub trait Api: Clone + fmt::Debug + Sized { /// finished. type Fence: DynFence + fmt::Debug; - type BindGroupLayout: fmt::Debug + WasmNotSendSync; + type BindGroupLayout: DynBindGroupLayout + fmt::Debug; type BindGroup: DynBindGroup; type PipelineLayout: DynPipelineLayout; type ShaderModule: DynShaderModule; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 5c836afd94..7f2d31a9f7 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -560,6 +560,8 @@ pub struct BindGroupLayout { entries: Arc<[wgt::BindGroupLayoutEntry]>, } +impl crate::DynBindGroupLayout for BindGroupLayout {} + #[derive(Clone, Debug, Default)] struct ResourceData { buffers: T, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 3f1ba28bc7..ba68e38d9c 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -727,6 +727,8 @@ pub struct BindGroupLayout { binding_arrays: Vec<(u32, NonZeroU32)>, } +impl crate::DynBindGroupLayout for BindGroupLayout {} + #[derive(Debug)] pub struct PipelineLayout { raw: vk::PipelineLayout, From ba06be2e37e5adeb2dc50cebdfd9a4e2811f29c8 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 27 Jul 2024 12:43:04 +0200 Subject: [PATCH 29/53] DynDevice create/destroy pipeline layout --- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dynamic/device.rs | 38 ++++++++++++++++++++++++++++++---- wgpu-hal/src/empty.rs | 2 +- wgpu-hal/src/gles/device.rs | 2 +- wgpu-hal/src/lib.rs | 6 +++--- wgpu-hal/src/metal/device.rs | 2 +- wgpu-hal/src/vulkan/device.rs | 2 +- 7 files changed, 42 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index b74c9ebca2..d99554241c 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -776,7 +776,7 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_layout( &self, - desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> Result { use naga::back::hlsl; // Pipeline layouts are implemented as RootSignature for D3D12. diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index a9adc36227..79b8f0d275 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -3,13 +3,13 @@ use crate::{ Api, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, - Device, DeviceError, DynBuffer, DynResource, MemoryRange, SamplerDescriptor, TextureDescriptor, - TextureViewDescriptor, + Device, DeviceError, DynBuffer, DynResource, MemoryRange, PipelineLayoutDescriptor, + SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, }; use super::{ - DynBindGroupLayout, DynCommandEncoder, DynQueue, DynResourceExt as _, DynSampler, DynTexture, - DynTextureView, + DynBindGroupLayout, DynCommandEncoder, DynPipelineLayout, DynQueue, DynResourceExt as _, + DynSampler, DynTexture, DynTextureView, }; pub trait DynDevice: DynResource { @@ -59,6 +59,12 @@ pub trait DynDevice: DynResource { desc: &BindGroupLayoutDescriptor, ) -> Result, DeviceError>; unsafe fn destroy_bind_group_layout(&self, bg_layout: Box); + + unsafe fn create_pipeline_layout( + &self, + desc: &PipelineLayoutDescriptor, + ) -> Result, DeviceError>; + unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box); } impl DynDevice for D { @@ -171,4 +177,28 @@ impl DynDevice for D { unsafe fn destroy_bind_group_layout(&self, bg_layout: Box) { unsafe { D::destroy_bind_group_layout(self, bg_layout.unbox()) }; } + + unsafe fn create_pipeline_layout( + &self, + desc: &PipelineLayoutDescriptor, + ) -> Result, DeviceError> { + let bind_group_layouts: Vec<_> = desc + .bind_group_layouts + .iter() + .map(|bgl| bgl.expect_downcast_ref()) + .collect(); + let desc = PipelineLayoutDescriptor { + label: desc.label, + bind_group_layouts: &bind_group_layouts, + push_constant_ranges: desc.push_constant_ranges, + flags: desc.flags, + }; + + unsafe { D::create_pipeline_layout(self, &desc) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box) { + unsafe { D::destroy_pipeline_layout(self, pipeline_layout.unbox()) }; + } } diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index b1d0eed6c4..3847756032 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -211,7 +211,7 @@ impl crate::Device for Context { unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} unsafe fn create_pipeline_layout( &self, - desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> DeviceResult { Ok(Resource) } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 6ce15269b0..81c17cae52 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1140,7 +1140,7 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_layout( &self, - desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> Result { use naga::back::glsl; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 26f4918fbf..c65b34a031 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -801,7 +801,7 @@ pub trait Device: WasmNotSendSync { unsafe fn destroy_bind_group_layout(&self, bg_layout: ::BindGroupLayout); unsafe fn create_pipeline_layout( &self, - desc: &PipelineLayoutDescriptor, + desc: &PipelineLayoutDescriptor<::BindGroupLayout>, ) -> Result<::PipelineLayout, DeviceError>; unsafe fn destroy_pipeline_layout(&self, pipeline_layout: ::PipelineLayout); unsafe fn create_bind_group( @@ -1743,10 +1743,10 @@ pub struct BindGroupLayoutDescriptor<'a> { } #[derive(Clone, Debug)] -pub struct PipelineLayoutDescriptor<'a, A: Api> { +pub struct PipelineLayoutDescriptor<'a, B: DynBindGroupLayout + ?Sized> { pub label: Label<'a>, pub flags: PipelineLayoutFlags, - pub bind_group_layouts: &'a [&'a A::BindGroupLayout], + pub bind_group_layouts: &'a [&'a B], pub push_constant_ranges: &'a [wgt::PushConstantRange], } diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 77631ab937..d1e58e5ce2 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -602,7 +602,7 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_layout( &self, - desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> DeviceResult { #[derive(Debug)] struct StageInfo { diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 9e9c50171f..f95cfdfec2 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1387,7 +1387,7 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_layout( &self, - desc: &crate::PipelineLayoutDescriptor, + desc: &crate::PipelineLayoutDescriptor, ) -> Result { //Note: not bothering with on stack array here as it's low frequency let vk_set_layouts = desc From f37a87170ecdcd7cce491b72a30b506fd2533993 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 27 Jul 2024 13:12:47 +0200 Subject: [PATCH 30/53] DynDevice create/destroy bind group bindgroup fixup --- wgpu-core/src/device/resource.rs | 2 +- wgpu-hal/src/dx12/device.rs | 8 +++- wgpu-hal/src/dx12/mod.rs | 3 ++ wgpu-hal/src/dynamic/device.rs | 70 +++++++++++++++++++++++++++++--- wgpu-hal/src/dynamic/mod.rs | 11 ++++- wgpu-hal/src/empty.rs | 3 +- wgpu-hal/src/gles/device.rs | 18 ++++++-- wgpu-hal/src/gles/mod.rs | 8 +++- wgpu-hal/src/lib.rs | 45 ++++++++++++-------- wgpu-hal/src/metal/device.rs | 8 +++- wgpu-hal/src/metal/mod.rs | 3 ++ wgpu-hal/src/vulkan/device.rs | 8 +++- wgpu-hal/src/vulkan/mod.rs | 3 ++ 13 files changed, 158 insertions(+), 32 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index de21f0a39a..104f54a40a 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2072,7 +2072,7 @@ impl Device { used: &mut BindGroupStates, used_texture_ranges: &mut Vec>, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> { view.same_device(self)?; let (pub_usage, internal_use) = self.texture_use_parameters( diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index d99554241c..a5120b0a41 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1104,7 +1104,13 @@ impl crate::Device for super::Device { unsafe fn create_bind_group( &self, - desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor< + super::BindGroupLayout, + super::Buffer, + super::Sampler, + super::TextureView, + super::AccelerationStructure, + >, ) -> Result { let mut cpu_views = desc .layout diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index fb0d9a1997..471e90f2b7 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -88,6 +88,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + AccelerationStructure, BindGroup, BindGroupLayout, Buffer, @@ -671,6 +672,8 @@ unsafe impl Sync for ComputePipeline {} #[derive(Debug)] pub struct AccelerationStructure {} +impl crate::DynAccelerationStructure for AccelerationStructure {} + impl SwapChain { unsafe fn release_resources(self) -> d3d12::ComPtr { self.raw diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 79b8f0d275..788c6dc175 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -2,14 +2,14 @@ #![allow(trivial_casts)] use crate::{ - Api, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, - Device, DeviceError, DynBuffer, DynResource, MemoryRange, PipelineLayoutDescriptor, - SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, + Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, + CommandEncoderDescriptor, Device, DeviceError, DynBuffer, DynResource, MemoryRange, + PipelineLayoutDescriptor, SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, }; use super::{ - DynBindGroupLayout, DynCommandEncoder, DynPipelineLayout, DynQueue, DynResourceExt as _, - DynSampler, DynTexture, DynTextureView, + DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynCommandEncoder, + DynPipelineLayout, DynQueue, DynResourceExt as _, DynSampler, DynTexture, DynTextureView, }; pub trait DynDevice: DynResource { @@ -65,6 +65,18 @@ pub trait DynDevice: DynResource { desc: &PipelineLayoutDescriptor, ) -> Result, DeviceError>; unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box); + + unsafe fn create_bind_group( + &self, + desc: &BindGroupDescriptor< + dyn DynBindGroupLayout, + dyn DynBuffer, + dyn DynSampler, + dyn DynTextureView, + dyn DynAccelerationStructure, + >, + ) -> Result, DeviceError>; + unsafe fn destroy_bind_group(&self, group: Box); } impl DynDevice for D { @@ -201,4 +213,52 @@ impl DynDevice for D { unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box) { unsafe { D::destroy_pipeline_layout(self, pipeline_layout.unbox()) }; } + + unsafe fn create_bind_group( + &self, + desc: &BindGroupDescriptor< + dyn DynBindGroupLayout, + dyn DynBuffer, + dyn DynSampler, + dyn DynTextureView, + dyn DynAccelerationStructure, + >, + ) -> Result, DeviceError> { + let buffers: Vec<_> = desc + .buffers + .iter() + .map(|b| b.clone().expect_downcast()) + .collect(); + let samplers: Vec<_> = desc + .samplers + .iter() + .map(|s| s.expect_downcast_ref()) + .collect(); + let textures: Vec<_> = desc + .textures + .iter() + .map(|t| t.clone().expect_downcast()) + .collect(); + let acceleration_structures: Vec<_> = desc + .acceleration_structures + .iter() + .map(|a| a.expect_downcast_ref()) + .collect(); + + let desc = BindGroupDescriptor { + label: desc.label.to_owned(), + layout: desc.layout.expect_downcast_ref(), + buffers: &buffers, + samplers: &samplers, + textures: &textures, + entries: desc.entries, + acceleration_structures: &acceleration_structures, + }; + + unsafe { D::create_bind_group(self, &desc) }.map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_bind_group(&self, group: Box) { + unsafe { D::destroy_bind_group(self, group.unbox()) }; + } } diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 2607ba44c3..3b7312fecf 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -12,7 +12,7 @@ use std::any::Any; use wgt::WasmNotSendSync; -use crate::BufferBinding; +use crate::{BufferBinding, TextureBinding}; /// Base trait for all resources, allows downcasting via [`Any`]. pub trait DynResource: Any + WasmNotSendSync + 'static { @@ -121,3 +121,12 @@ impl<'a> BufferBinding<'a, dyn DynBuffer> { } } } + +impl<'a> TextureBinding<'a, dyn DynTextureView> { + pub fn expect_downcast(self) -> TextureBinding<'a, T> { + TextureBinding { + view: self.view.expect_downcast_ref(), + usage: self.usage, + } + } +} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 3847756032..1ca1ae6545 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -42,6 +42,7 @@ impl crate::Api for Api { crate::impl_dyn_resource!(Context, Encoder, Resource); +impl crate::DynAccelerationStructure for Resource {} impl crate::DynBindGroup for Resource {} impl crate::DynBindGroupLayout for Resource {} impl crate::DynBuffer for Resource {} @@ -218,7 +219,7 @@ impl crate::Device for Context { unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} unsafe fn create_bind_group( &self, - desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor, ) -> DeviceResult { Ok(Resource) } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 81c17cae52..777225edfc 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1232,7 +1232,13 @@ impl crate::Device for super::Device { unsafe fn create_bind_group( &self, - desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor< + super::BindGroupLayout, + super::Buffer, + super::Sampler, + super::TextureView, + super::AccelerationStructure, + >, ) -> Result { let mut contents = Vec::new(); @@ -1589,7 +1595,7 @@ impl crate::Device for super::Device { unsafe fn create_acceleration_structure( &self, _desc: &crate::AccelerationStructureDescriptor, - ) -> Result<(), crate::DeviceError> { + ) -> Result { unimplemented!() } unsafe fn get_acceleration_structure_build_sizes<'a>( @@ -1600,11 +1606,15 @@ impl crate::Device for super::Device { } unsafe fn get_acceleration_structure_device_address( &self, - _acceleration_structure: &(), + _acceleration_structure: &super::AccelerationStructure, ) -> wgt::BufferAddress { unimplemented!() } - unsafe fn destroy_acceleration_structure(&self, _acceleration_structure: ()) {} + unsafe fn destroy_acceleration_structure( + &self, + _acceleration_structure: super::AccelerationStructure, + ) { + } fn get_internal_counters(&self) -> wgt::HalCounters { self.counters.clone() diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 9fd40d4d26..3ef0699c08 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -153,7 +153,7 @@ impl crate::Api for Api { type Sampler = Sampler; type QuerySet = QuerySet; type Fence = Fence; - type AccelerationStructure = (); + type AccelerationStructure = AccelerationStructure; type PipelineCache = (); type BindGroupLayout = BindGroupLayout; @@ -165,6 +165,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + AccelerationStructure, BindGroup, BindGroupLayout, Buffer, @@ -750,6 +751,11 @@ impl Fence { } } +#[derive(Debug)] +pub struct AccelerationStructure; + +impl crate::DynAccelerationStructure for AccelerationStructure {} + #[derive(Clone, Debug, PartialEq)] struct StencilOps { pass: u32, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index c65b34a031..016421b4ad 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -443,7 +443,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type ComputePipeline: DynComputePipeline; type PipelineCache: fmt::Debug + WasmNotSendSync; - type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static; + type AccelerationStructure: DynAccelerationStructure + fmt::Debug + 'static; } pub trait Instance: Sized + WasmNotSendSync { @@ -804,9 +804,17 @@ pub trait Device: WasmNotSendSync { desc: &PipelineLayoutDescriptor<::BindGroupLayout>, ) -> Result<::PipelineLayout, DeviceError>; unsafe fn destroy_pipeline_layout(&self, pipeline_layout: ::PipelineLayout); + + #[allow(clippy::type_complexity)] unsafe fn create_bind_group( &self, - desc: &BindGroupDescriptor, + desc: &BindGroupDescriptor< + ::BindGroupLayout, + ::Buffer, + ::Sampler, + ::TextureView, + ::AccelerationStructure, + >, ) -> Result<::BindGroup, DeviceError>; unsafe fn destroy_bind_group(&self, group: ::BindGroup); @@ -1776,10 +1784,9 @@ pub struct BufferBinding<'a, B: DynBuffer + ?Sized> { pub size: Option, } -// Rust gets confused about the impl requirements for `A` -impl Clone for BufferBinding<'_, B> { +impl<'a, T: DynBuffer + ?Sized> Clone for BufferBinding<'a, T> { fn clone(&self) -> Self { - Self { + BufferBinding { buffer: self.buffer, offset: self.offset, size: self.size, @@ -1788,15 +1795,14 @@ impl Clone for BufferBinding<'_, B> { } #[derive(Debug)] -pub struct TextureBinding<'a, A: Api> { - pub view: &'a A::TextureView, +pub struct TextureBinding<'a, T: DynTextureView + ?Sized> { + pub view: &'a T, pub usage: TextureUses, } -// Rust gets confused about the impl requirements for `A` -impl Clone for TextureBinding<'_, A> { +impl<'a, T: DynTextureView + ?Sized> Clone for TextureBinding<'a, T> { fn clone(&self) -> Self { - Self { + TextureBinding { view: self.view, usage: self.usage, } @@ -1820,14 +1826,21 @@ pub struct BindGroupEntry { /// of the corresponding resource array, selected by the relevant /// `BindGroupLayoutEntry`. #[derive(Clone, Debug)] -pub struct BindGroupDescriptor<'a, A: Api> { +pub struct BindGroupDescriptor< + 'a, + Bgl: DynBindGroupLayout + ?Sized, + B: DynBuffer + ?Sized, + S: DynSampler + ?Sized, + T: DynTextureView + ?Sized, + A: DynAccelerationStructure + ?Sized, +> { pub label: Label<'a>, - pub layout: &'a A::BindGroupLayout, - pub buffers: &'a [BufferBinding<'a, A::Buffer>], - pub samplers: &'a [&'a A::Sampler], - pub textures: &'a [TextureBinding<'a, A>], + pub layout: &'a Bgl, + pub buffers: &'a [BufferBinding<'a, B>], + pub samplers: &'a [&'a S], + pub textures: &'a [TextureBinding<'a, T>], pub entries: &'a [BindGroupEntry], - pub acceleration_structures: &'a [&'a A::AccelerationStructure], + pub acceleration_structures: &'a [&'a A], } #[derive(Clone, Debug)] diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index d1e58e5ce2..7fb7b5132b 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -776,7 +776,13 @@ impl crate::Device for super::Device { unsafe fn create_bind_group( &self, - desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor< + super::BindGroupLayout, + super::Buffer, + super::Sampler, + super::TextureView, + super::AccelerationStructure, + >, ) -> DeviceResult { let mut bg = super::BindGroup::default(); for (&stage, counter) in super::NAGA_STAGES.iter().zip(bg.counters.iter_mut()) { diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 7f2d31a9f7..7b4dc8b22e 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -72,6 +72,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + AccelerationStructure, BindGroup, BindGroupLayout, Buffer, @@ -931,3 +932,5 @@ unsafe impl Sync for CommandBuffer {} #[derive(Debug)] pub struct AccelerationStructure; + +impl crate::DynAccelerationStructure for AccelerationStructure {} diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index f95cfdfec2..5d0aa39760 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1453,7 +1453,13 @@ impl crate::Device for super::Device { unsafe fn create_bind_group( &self, - desc: &crate::BindGroupDescriptor, + desc: &crate::BindGroupDescriptor< + super::BindGroupLayout, + super::Buffer, + super::Sampler, + super::TextureView, + super::AccelerationStructure, + >, ) -> Result { let mut vk_sets = unsafe { self.desc_allocator.lock().allocate( diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index ba68e38d9c..816bf37e5f 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -79,6 +79,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + AccelerationStructure, BindGroup, BindGroupLayout, Buffer, @@ -670,6 +671,8 @@ pub struct AccelerationStructure { block: Mutex>, } +impl crate::DynAccelerationStructure for AccelerationStructure {} + #[derive(Debug)] pub struct Texture { raw: vk::Image, From 533def2b0947780a298e8d3709f3c2f5c1010ee2 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 27 Jul 2024 18:16:41 +0200 Subject: [PATCH 31/53] DynDevice create/destroy ShaderModule --- wgpu-hal/src/dynamic/device.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 788c6dc175..0e13273852 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -4,12 +4,14 @@ use crate::{ Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, Device, DeviceError, DynBuffer, DynResource, MemoryRange, - PipelineLayoutDescriptor, SamplerDescriptor, TextureDescriptor, TextureViewDescriptor, + PipelineLayoutDescriptor, SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, + TextureDescriptor, TextureViewDescriptor, }; use super::{ DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynCommandEncoder, - DynPipelineLayout, DynQueue, DynResourceExt as _, DynSampler, DynTexture, DynTextureView, + DynPipelineLayout, DynQueue, DynResourceExt as _, DynSampler, DynShaderModule, DynTexture, + DynTextureView, }; pub trait DynDevice: DynResource { @@ -77,6 +79,13 @@ pub trait DynDevice: DynResource { >, ) -> Result, DeviceError>; unsafe fn destroy_bind_group(&self, group: Box); + + unsafe fn create_shader_module( + &self, + desc: &ShaderModuleDescriptor, + shader: ShaderInput, + ) -> Result, ShaderError>; + unsafe fn destroy_shader_module(&self, module: Box); } impl DynDevice for D { @@ -261,4 +270,17 @@ impl DynDevice for D { unsafe fn destroy_bind_group(&self, group: Box) { unsafe { D::destroy_bind_group(self, group.unbox()) }; } + + unsafe fn create_shader_module( + &self, + desc: &ShaderModuleDescriptor, + shader: ShaderInput, + ) -> Result, ShaderError> { + unsafe { D::create_shader_module(self, desc, shader) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_shader_module(&self, module: Box) { + unsafe { D::destroy_shader_module(self, module.unbox()) }; + } } From bf1bf410faea91d89035ed3ab996675341bde06c Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 28 Jul 2024 09:56:20 +0200 Subject: [PATCH 32/53] DynDevice create/destroy compute/render pipeline --- wgpu-hal/src/dx12/device.rs | 22 ++++++--- wgpu-hal/src/dx12/mod.rs | 7 ++- wgpu-hal/src/dynamic/device.rs | 84 ++++++++++++++++++++++++++++++++-- wgpu-hal/src/dynamic/mod.rs | 13 +++++- wgpu-hal/src/empty.rs | 5 +- wgpu-hal/src/gles/device.rs | 22 ++++++--- wgpu-hal/src/gles/mod.rs | 8 +++- wgpu-hal/src/lib.rs | 54 +++++++++++++++------- wgpu-hal/src/metal/device.rs | 20 +++++--- wgpu-hal/src/metal/mod.rs | 8 +++- wgpu-hal/src/vulkan/device.rs | 25 ++++++---- wgpu-hal/src/vulkan/mod.rs | 2 + 12 files changed, 215 insertions(+), 55 deletions(-) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index a5120b0a41..b58b882b44 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -211,10 +211,10 @@ impl super::Device { /// allowed to be a subset of the vertex outputs. fn load_shader( &self, - stage: &crate::ProgrammableStage, + stage: &crate::ProgrammableStage, layout: &super::PipelineLayout, naga_stage: naga::ShaderStage, - fragment_stage: Option<&crate::ProgrammableStage>, + fragment_stage: Option<&crate::ProgrammableStage>, ) -> Result { use naga::back::hlsl; @@ -1320,7 +1320,11 @@ impl crate::Device for super::Device { unsafe fn create_render_pipeline( &self, - desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let (topology_class, topology) = conv::map_topology(desc.primitive.topology); let mut shader_stages = wgt::ShaderStages::VERTEX; @@ -1515,7 +1519,11 @@ impl crate::Device for super::Device { unsafe fn create_compute_pipeline( &self, - desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let blob_cs = self.load_shader(&desc.stage, desc.layout, naga::ShaderStage::Compute, None)?; @@ -1559,10 +1567,10 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_cache( &self, _desc: &crate::PipelineCacheDescriptor<'_>, - ) -> Result<(), crate::PipelineCacheError> { - Ok(()) + ) -> Result { + Ok(super::PipelineCache) } - unsafe fn destroy_pipeline_cache(&self, (): ()) {} + unsafe fn destroy_pipeline_cache(&self, _: super::PipelineCache) {} unsafe fn create_query_set( &self, diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 471e90f2b7..e5db9fc234 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -82,7 +82,7 @@ impl crate::Api for Api { type ShaderModule = ShaderModule; type RenderPipeline = RenderPipeline; type ComputePipeline = ComputePipeline; - type PipelineCache = (); + type PipelineCache = PipelineCache; type AccelerationStructure = AccelerationStructure; } @@ -669,6 +669,11 @@ impl crate::DynComputePipeline for ComputePipeline {} unsafe impl Send for ComputePipeline {} unsafe impl Sync for ComputePipeline {} +#[derive(Debug)] +pub struct PipelineCache; + +impl crate::DynPipelineCache for PipelineCache {} + #[derive(Debug)] pub struct AccelerationStructure {} diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 0e13273852..4d3b978267 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -3,15 +3,16 @@ use crate::{ Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, - CommandEncoderDescriptor, Device, DeviceError, DynBuffer, DynResource, MemoryRange, - PipelineLayoutDescriptor, SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, - TextureDescriptor, TextureViewDescriptor, + CommandEncoderDescriptor, ComputePipelineDescriptor, Device, DeviceError, DynBuffer, + DynResource, MemoryRange, PipelineError, PipelineLayoutDescriptor, RenderPipelineDescriptor, + SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, TextureDescriptor, + TextureViewDescriptor, }; use super::{ DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynCommandEncoder, - DynPipelineLayout, DynQueue, DynResourceExt as _, DynSampler, DynShaderModule, DynTexture, - DynTextureView, + DynComputePipeline, DynPipelineCache, DynPipelineLayout, DynQueue, DynRenderPipeline, + DynResourceExt as _, DynSampler, DynShaderModule, DynTexture, DynTextureView, }; pub trait DynDevice: DynResource { @@ -86,6 +87,26 @@ pub trait DynDevice: DynResource { shader: ShaderInput, ) -> Result, ShaderError>; unsafe fn destroy_shader_module(&self, module: Box); + + unsafe fn create_render_pipeline( + &self, + desc: &RenderPipelineDescriptor< + dyn DynPipelineLayout, + dyn DynShaderModule, + dyn DynPipelineCache, + >, + ) -> Result, PipelineError>; + unsafe fn destroy_render_pipeline(&self, pipeline: Box); + + unsafe fn create_compute_pipeline( + &self, + desc: &ComputePipelineDescriptor< + dyn DynPipelineLayout, + dyn DynShaderModule, + dyn DynPipelineCache, + >, + ) -> Result, PipelineError>; + unsafe fn destroy_compute_pipeline(&self, pipeline: Box); } impl DynDevice for D { @@ -283,4 +304,57 @@ impl DynDevice for D { unsafe fn destroy_shader_module(&self, module: Box) { unsafe { D::destroy_shader_module(self, module.unbox()) }; } + + unsafe fn create_render_pipeline( + &self, + desc: &RenderPipelineDescriptor< + dyn DynPipelineLayout, + dyn DynShaderModule, + dyn DynPipelineCache, + >, + ) -> Result, PipelineError> { + let desc = RenderPipelineDescriptor { + label: desc.label, + layout: desc.layout.expect_downcast_ref(), + vertex_buffers: desc.vertex_buffers, + vertex_stage: desc.vertex_stage.clone().expect_downcast(), + primitive: desc.primitive, + depth_stencil: desc.depth_stencil.clone(), + multisample: desc.multisample, + fragment_stage: desc.fragment_stage.clone().map(|f| f.expect_downcast()), + color_targets: desc.color_targets, + multiview: desc.multiview, + cache: desc.cache.map(|c| c.expect_downcast_ref()), + }; + + unsafe { D::create_render_pipeline(self, &desc) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_render_pipeline(&self, pipeline: Box) { + unsafe { D::destroy_render_pipeline(self, pipeline.unbox()) }; + } + + unsafe fn create_compute_pipeline( + &self, + desc: &ComputePipelineDescriptor< + dyn DynPipelineLayout, + dyn DynShaderModule, + dyn DynPipelineCache, + >, + ) -> Result, PipelineError> { + let desc = ComputePipelineDescriptor { + label: desc.label, + layout: desc.layout.expect_downcast_ref(), + stage: desc.stage.clone().expect_downcast(), + cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()), + }; + + unsafe { D::create_compute_pipeline(self, &desc) } + .map(|b| Box::new(b) as Box) + } + + unsafe fn destroy_compute_pipeline(&self, pipeline: Box) { + unsafe { D::destroy_compute_pipeline(self, pipeline.unbox()) }; + } } diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 3b7312fecf..9b4875bc76 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -12,7 +12,7 @@ use std::any::Any; use wgt::WasmNotSendSync; -use crate::{BufferBinding, TextureBinding}; +use crate::{BufferBinding, ProgrammableStage, TextureBinding}; /// Base trait for all resources, allows downcasting via [`Any`]. pub trait DynResource: Any + WasmNotSendSync + 'static { @@ -130,3 +130,14 @@ impl<'a> TextureBinding<'a, dyn DynTextureView> { } } } + +impl<'a> ProgrammableStage<'a, dyn DynShaderModule> { + fn expect_downcast(self) -> ProgrammableStage<'a, T> { + ProgrammableStage { + module: self.module.expect_downcast_ref(), + entry_point: self.entry_point, + constants: self.constants, + zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory, + } + } +} diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 1ca1ae6545..87139ce0f0 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -49,6 +49,7 @@ impl crate::DynBuffer for Resource {} impl crate::DynCommandBuffer for Resource {} impl crate::DynComputePipeline for Resource {} impl crate::DynFence for Resource {} +impl crate::DynPipelineCache for Resource {} impl crate::DynPipelineLayout for Resource {} impl crate::DynQuerySet for Resource {} impl crate::DynRenderPipeline for Resource {} @@ -235,14 +236,14 @@ impl crate::Device for Context { unsafe fn destroy_shader_module(&self, module: Resource) {} unsafe fn create_render_pipeline( &self, - desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor, ) -> Result { Ok(Resource) } unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {} unsafe fn create_compute_pipeline( &self, - desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor, ) -> Result { Ok(Resource) } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 777225edfc..f459d970fc 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -13,7 +13,7 @@ use std::sync::atomic::Ordering; type ShaderStage<'a> = ( naga::ShaderStage, - &'a crate::ProgrammableStage<'a, super::Api>, + &'a crate::ProgrammableStage<'a, super::ShaderModule>, ); type NameBindingMap = rustc_hash::FxHashMap; @@ -205,7 +205,7 @@ impl super::Device { fn create_shader( gl: &glow::Context, naga_stage: naga::ShaderStage, - stage: &crate::ProgrammableStage, + stage: &crate::ProgrammableStage, context: CompilationContext, program: glow::Program, ) -> Result { @@ -1346,7 +1346,11 @@ impl crate::Device for super::Device { unsafe fn create_render_pipeline( &self, - desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let gl = &self.shared.context.lock(); let mut shaders = ArrayVec::new(); @@ -1436,7 +1440,11 @@ impl crate::Device for super::Device { unsafe fn create_compute_pipeline( &self, - desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let gl = &self.shared.context.lock(); let mut shaders = ArrayVec::new(); @@ -1469,12 +1477,12 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_cache( &self, _: &crate::PipelineCacheDescriptor<'_>, - ) -> Result<(), crate::PipelineCacheError> { + ) -> Result { // Even though the cache doesn't do anything, we still return something here // as the least bad option - Ok(()) + Ok(super::PipelineCache) } - unsafe fn destroy_pipeline_cache(&self, (): ()) {} + unsafe fn destroy_pipeline_cache(&self, _: super::PipelineCache) {} #[cfg_attr(target_arch = "wasm32", allow(unused))] unsafe fn create_query_set( diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 3ef0699c08..617d3f0729 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -154,7 +154,7 @@ impl crate::Api for Api { type QuerySet = QuerySet; type Fence = Fence; type AccelerationStructure = AccelerationStructure; - type PipelineCache = (); + type PipelineCache = PipelineCache; type BindGroupLayout = BindGroupLayout; type BindGroup = BindGroup; @@ -174,6 +174,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + PipelineCache, PipelineLayout, QuerySet, Queue, @@ -756,6 +757,11 @@ pub struct AccelerationStructure; impl crate::DynAccelerationStructure for AccelerationStructure {} +#[derive(Debug)] +pub struct PipelineCache; + +impl crate::DynPipelineCache for PipelineCache {} + #[derive(Clone, Debug, PartialEq)] struct StencilOps { pass: u32, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 016421b4ad..38e0cd1f5b 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -441,7 +441,7 @@ pub trait Api: Clone + fmt::Debug + Sized { type ShaderModule: DynShaderModule; type RenderPipeline: DynRenderPipeline; type ComputePipeline: DynComputePipeline; - type PipelineCache: fmt::Debug + WasmNotSendSync; + type PipelineCache: DynPipelineCache + fmt::Debug; type AccelerationStructure: DynAccelerationStructure + fmt::Debug + 'static; } @@ -824,16 +824,29 @@ pub trait Device: WasmNotSendSync { shader: ShaderInput, ) -> Result<::ShaderModule, ShaderError>; unsafe fn destroy_shader_module(&self, module: ::ShaderModule); + + #[allow(clippy::type_complexity)] unsafe fn create_render_pipeline( &self, - desc: &RenderPipelineDescriptor, + desc: &RenderPipelineDescriptor< + ::PipelineLayout, + ::ShaderModule, + ::PipelineCache, + >, ) -> Result<::RenderPipeline, PipelineError>; unsafe fn destroy_render_pipeline(&self, pipeline: ::RenderPipeline); + + #[allow(clippy::type_complexity)] unsafe fn create_compute_pipeline( &self, - desc: &ComputePipelineDescriptor, + desc: &ComputePipelineDescriptor< + ::PipelineLayout, + ::ShaderModule, + ::PipelineCache, + >, ) -> Result<::ComputePipeline, PipelineError>; unsafe fn destroy_compute_pipeline(&self, pipeline: ::ComputePipeline); + unsafe fn create_pipeline_cache( &self, desc: &PipelineCacheDescriptor<'_>, @@ -1887,9 +1900,9 @@ pub struct DebugSource { /// Describes a programmable pipeline stage. #[derive(Debug)] -pub struct ProgrammableStage<'a, A: Api> { +pub struct ProgrammableStage<'a, M: DynShaderModule + ?Sized> { /// The compiled shader module for this stage. - pub module: &'a A::ShaderModule, + pub module: &'a M, /// The name of the entry point in the compiled shader. There must be a function with this name /// in the shader. pub entry_point: &'a str, @@ -1902,8 +1915,7 @@ pub struct ProgrammableStage<'a, A: Api> { pub zero_initialize_workgroup_memory: bool, } -// Rust gets confused about the impl requirements for `A` -impl Clone for ProgrammableStage<'_, A> { +impl Clone for ProgrammableStage<'_, M> { fn clone(&self) -> Self { Self { module: self.module, @@ -1916,14 +1928,19 @@ impl Clone for ProgrammableStage<'_, A> { /// Describes a compute pipeline. #[derive(Clone, Debug)] -pub struct ComputePipelineDescriptor<'a, A: Api> { +pub struct ComputePipelineDescriptor< + 'a, + Pl: DynPipelineLayout + ?Sized, + M: DynShaderModule + ?Sized, + Pc: DynPipelineCache + ?Sized, +> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. - pub layout: &'a A::PipelineLayout, + pub layout: &'a Pl, /// The compiled compute stage and its entry point. - pub stage: ProgrammableStage<'a, A>, + pub stage: ProgrammableStage<'a, M>, /// The cache which will be used and filled when compiling this pipeline - pub cache: Option<&'a A::PipelineCache>, + pub cache: Option<&'a Pc>, } pub struct PipelineCacheDescriptor<'a> { @@ -1944,14 +1961,19 @@ pub struct VertexBufferLayout<'a> { /// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] -pub struct RenderPipelineDescriptor<'a, A: Api> { +pub struct RenderPipelineDescriptor< + 'a, + Pl: DynPipelineLayout + ?Sized, + M: DynShaderModule + ?Sized, + Pc: DynPipelineCache + ?Sized, +> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. - pub layout: &'a A::PipelineLayout, + pub layout: &'a Pl, /// The format of any vertex buffers used with this pipeline. pub vertex_buffers: &'a [VertexBufferLayout<'a>], /// The vertex stage for this pipeline. - pub vertex_stage: ProgrammableStage<'a, A>, + pub vertex_stage: ProgrammableStage<'a, M>, /// The properties of the pipeline at the primitive assembly and rasterization level. pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. @@ -1959,14 +1981,14 @@ pub struct RenderPipelineDescriptor<'a, A: Api> { /// The multi-sampling properties of the pipeline. pub multisample: wgt::MultisampleState, /// The fragment stage for this pipeline. - pub fragment_stage: Option>, + pub fragment_stage: Option>, /// The effect of draw calls on the color aspect of the output target. pub color_targets: &'a [Option], /// If the pipeline will be used with a multiview render pass, this indicates how many array /// layers the attachments will have. pub multiview: Option, /// The cache which will be used and filled when compiling this pipeline - pub cache: Option<&'a A::PipelineCache>, + pub cache: Option<&'a Pc>, } #[derive(Debug, Clone)] diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 7fb7b5132b..a17ca2ec42 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -99,7 +99,7 @@ const fn convert_vertex_format_to_naga(format: wgt::VertexFormat) -> naga::back: impl super::Device { fn load_shader( &self, - stage: &crate::ProgrammableStage, + stage: &crate::ProgrammableStage, vertex_buffer_mappings: &[naga::back::msl::VertexBufferMapping], layout: &super::PipelineLayout, primitive_class: metal::MTLPrimitiveTopologyClass, @@ -898,7 +898,11 @@ impl crate::Device for super::Device { unsafe fn create_render_pipeline( &self, - desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { objc::rc::autoreleasepool(|| { let descriptor = metal::RenderPipelineDescriptor::new(); @@ -1169,7 +1173,11 @@ impl crate::Device for super::Device { unsafe fn create_compute_pipeline( &self, - desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { objc::rc::autoreleasepool(|| { let descriptor = metal::ComputePipelineDescriptor::new(); @@ -1232,10 +1240,10 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_cache( &self, _desc: &crate::PipelineCacheDescriptor<'_>, - ) -> Result<(), crate::PipelineCacheError> { - Ok(()) + ) -> Result { + Ok(super::PipelineCache) } - unsafe fn destroy_pipeline_cache(&self, (): ()) {} + unsafe fn destroy_pipeline_cache(&self, _: super::PipelineCache) {} unsafe fn create_query_set( &self, diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 7b4dc8b22e..f861474f8a 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -66,7 +66,7 @@ impl crate::Api for Api { type ShaderModule = ShaderModule; type RenderPipeline = RenderPipeline; type ComputePipeline = ComputePipeline; - type PipelineCache = (); + type PipelineCache = PipelineCache; type AccelerationStructure = AccelerationStructure; } @@ -81,6 +81,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + PipelineCache, PipelineLayout, QuerySet, Queue, @@ -930,6 +931,11 @@ impl crate::DynCommandBuffer for CommandBuffer {} unsafe impl Send for CommandBuffer {} unsafe impl Sync for CommandBuffer {} +#[derive(Debug)] +pub struct PipelineCache; + +impl crate::DynPipelineCache for PipelineCache {} + #[derive(Debug)] pub struct AccelerationStructure; diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 5d0aa39760..e7be52a097 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1,4 +1,4 @@ -use super::{conv, PipelineCache}; +use super::conv; use arrayvec::ArrayVec; use ash::{khr, vk}; @@ -709,7 +709,7 @@ impl super::Device { fn compile_stage( &self, - stage: &crate::ProgrammableStage, + stage: &crate::ProgrammableStage, naga_stage: naga::ShaderStage, binding_map: &naga::back::spv::BindingMap, ) -> Result { @@ -1725,7 +1725,11 @@ impl crate::Device for super::Device { unsafe fn create_render_pipeline( &self, - desc: &crate::RenderPipelineDescriptor, + desc: &crate::RenderPipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let dynamic_states = [ vk::DynamicState::VIEWPORT, @@ -1955,6 +1959,7 @@ impl crate::Device for super::Device { Ok(super::RenderPipeline { raw }) } + unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) { unsafe { self.shared.raw.destroy_pipeline(pipeline.raw, None) }; @@ -1963,7 +1968,11 @@ impl crate::Device for super::Device { unsafe fn create_compute_pipeline( &self, - desc: &crate::ComputePipelineDescriptor, + desc: &crate::ComputePipelineDescriptor< + super::PipelineLayout, + super::ShaderModule, + super::PipelineCache, + >, ) -> Result { let compiled = self.compile_stage( &desc.stage, @@ -2015,7 +2024,7 @@ impl crate::Device for super::Device { unsafe fn create_pipeline_cache( &self, desc: &crate::PipelineCacheDescriptor<'_>, - ) -> Result { + ) -> Result { let mut info = vk::PipelineCacheCreateInfo::default(); if let Some(data) = desc.data { info = info.initial_data(data) @@ -2024,12 +2033,12 @@ impl crate::Device for super::Device { let raw = unsafe { self.shared.raw.create_pipeline_cache(&info, None) } .map_err(crate::DeviceError::from)?; - Ok(PipelineCache { raw }) + Ok(super::PipelineCache { raw }) } fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> { Some(self.shared.pipeline_cache_validation_key) } - unsafe fn destroy_pipeline_cache(&self, cache: PipelineCache) { + unsafe fn destroy_pipeline_cache(&self, cache: super::PipelineCache) { unsafe { self.shared.raw.destroy_pipeline_cache(cache.raw, None) } } unsafe fn create_query_set( @@ -2160,7 +2169,7 @@ impl crate::Device for super::Device { } } - unsafe fn pipeline_cache_get_data(&self, cache: &PipelineCache) -> Option> { + unsafe fn pipeline_cache_get_data(&self, cache: &super::PipelineCache) -> Option> { let data = unsafe { self.raw_device().get_pipeline_cache_data(cache.raw) }; data.ok() } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 816bf37e5f..a77ff444b6 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -862,6 +862,8 @@ pub struct PipelineCache { raw: vk::PipelineCache, } +impl crate::DynPipelineCache for PipelineCache {} + #[derive(Debug)] pub struct QuerySet { raw: vk::QueryPool, From 7d8f753ddcd87ac9373755674707094d6d417ea0 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 28 Jul 2024 10:07:40 +0200 Subject: [PATCH 33/53] DynDevice pipeline cache --- wgpu-hal/src/dynamic/device.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 4d3b978267..bf5a4d40e6 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -4,9 +4,9 @@ use crate::{ Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, ComputePipelineDescriptor, Device, DeviceError, DynBuffer, - DynResource, MemoryRange, PipelineError, PipelineLayoutDescriptor, RenderPipelineDescriptor, - SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, TextureDescriptor, - TextureViewDescriptor, + DynResource, MemoryRange, PipelineCacheDescriptor, PipelineCacheError, PipelineError, + PipelineLayoutDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderError, + ShaderInput, ShaderModuleDescriptor, TextureDescriptor, TextureViewDescriptor, }; use super::{ @@ -107,6 +107,15 @@ pub trait DynDevice: DynResource { >, ) -> Result, PipelineError>; unsafe fn destroy_compute_pipeline(&self, pipeline: Box); + + unsafe fn create_pipeline_cache( + &self, + desc: &PipelineCacheDescriptor<'_>, + ) -> Result, PipelineCacheError>; + fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> { + None + } + unsafe fn destroy_pipeline_cache(&self, cache: Box); } impl DynDevice for D { @@ -357,4 +366,20 @@ impl DynDevice for D { unsafe fn destroy_compute_pipeline(&self, pipeline: Box) { unsafe { D::destroy_compute_pipeline(self, pipeline.unbox()) }; } + + unsafe fn create_pipeline_cache( + &self, + desc: &PipelineCacheDescriptor<'_>, + ) -> Result, PipelineCacheError> { + unsafe { D::create_pipeline_cache(self, desc) } + .map(|b| Box::new(b) as Box) + } + + fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> { + D::pipeline_cache_validation_key(self) + } + + unsafe fn destroy_pipeline_cache(&self, pipeline_cache: Box) { + unsafe { D::destroy_pipeline_cache(self, pipeline_cache.unbox()) }; + } } From af358463c61a08fac893858516fb120727fc2802 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 28 Jul 2024 10:11:41 +0200 Subject: [PATCH 34/53] DynDevice create/destroy query set --- wgpu-hal/src/dynamic/device.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index bf5a4d40e6..3bfd9df787 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -4,15 +4,16 @@ use crate::{ Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, ComputePipelineDescriptor, Device, DeviceError, DynBuffer, - DynResource, MemoryRange, PipelineCacheDescriptor, PipelineCacheError, PipelineError, + DynResource, Label, MemoryRange, PipelineCacheDescriptor, PipelineCacheError, PipelineError, PipelineLayoutDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, TextureDescriptor, TextureViewDescriptor, }; use super::{ DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynCommandEncoder, - DynComputePipeline, DynPipelineCache, DynPipelineLayout, DynQueue, DynRenderPipeline, - DynResourceExt as _, DynSampler, DynShaderModule, DynTexture, DynTextureView, + DynComputePipeline, DynPipelineCache, DynPipelineLayout, DynQuerySet, DynQueue, + DynRenderPipeline, DynResourceExt as _, DynSampler, DynShaderModule, DynTexture, + DynTextureView, }; pub trait DynDevice: DynResource { @@ -116,6 +117,12 @@ pub trait DynDevice: DynResource { None } unsafe fn destroy_pipeline_cache(&self, cache: Box); + + unsafe fn create_query_set( + &self, + desc: &wgt::QuerySetDescriptor; type Surface: DynSurface + Surface; - type Adapter: Adapter; + type Adapter: DynAdapter + Adapter; type Device: DynDevice + Device; type Queue: DynQueue + Queue; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index f861474f8a..728ee8f496 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -72,6 +72,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + Adapter, AccelerationStructure, BindGroup, BindGroupLayout, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index a77ff444b6..90c2cf2a0c 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -79,6 +79,7 @@ impl crate::Api for Api { } crate::impl_dyn_resource!( + Adapter, AccelerationStructure, BindGroup, BindGroupLayout, From 75aaa130d62afab589a599e0c5cbc0a5515d5941 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 4 Aug 2024 17:37:02 +0200 Subject: [PATCH 43/53] introduce DynInstance --- wgpu-hal/src/dx12/mod.rs | 1 + wgpu-hal/src/dynamic/instance.rs | 53 ++++++++++++++++++++++++++++++++ wgpu-hal/src/dynamic/mod.rs | 2 ++ wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 8 ++--- wgpu-hal/src/metal/mod.rs | 1 + wgpu-hal/src/vulkan/mod.rs | 1 + 7 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 wgpu-hal/src/dynamic/instance.rs diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index fc3f2fbd12..8401bbe1eb 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -98,6 +98,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + Instance, PipelineCache, PipelineLayout, QuerySet, diff --git a/wgpu-hal/src/dynamic/instance.rs b/wgpu-hal/src/dynamic/instance.rs new file mode 100644 index 0000000000..80d834544d --- /dev/null +++ b/wgpu-hal/src/dynamic/instance.rs @@ -0,0 +1,53 @@ +// Box casts are needed, alternative would be a temporaries which are more verbose and not more expressive. +#![allow(trivial_casts)] + +use crate::{Capabilities, Instance, InstanceError}; + +use super::{DynAdapter, DynResource, DynResourceExt as _, DynSurface}; + +pub struct DynExposedAdapter { + pub adapter: Box, + pub info: wgt::AdapterInfo, + pub features: wgt::Features, + pub capabilities: Capabilities, +} + +pub trait DynInstance: DynResource { + unsafe fn create_surface( + &self, + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, + ) -> Result, InstanceError>; + + unsafe fn enumerate_adapters( + &self, + surface_hint: Option<&dyn DynSurface>, + ) -> Vec; +} + +impl DynInstance for I { + unsafe fn create_surface( + &self, + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, + ) -> Result, InstanceError> { + unsafe { I::create_surface(self, display_handle, window_handle) } + .map(|surface| Box::new(surface) as Box) + } + + unsafe fn enumerate_adapters( + &self, + surface_hint: Option<&dyn DynSurface>, + ) -> Vec { + let surface_hint = surface_hint.map(|s| s.expect_downcast_ref()); + unsafe { I::enumerate_adapters(self, surface_hint) } + .into_iter() + .map(|exposed| DynExposedAdapter { + adapter: Box::new(exposed.adapter), + info: exposed.info, + features: exposed.features, + capabilities: exposed.capabilities, + }) + .collect() + } +} diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index 490251a511..5509d7cce6 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -1,12 +1,14 @@ mod adapter; mod command; mod device; +mod instance; mod queue; mod surface; pub use adapter::{DynAdapter, DynOpenDevice}; pub use command::DynCommandEncoder; pub use device::DynDevice; +pub use instance::{DynExposedAdapter, DynInstance}; pub use queue::DynQueue; pub use surface::{DynAcquiredSurfaceTexture, DynSurface}; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 86ee6df29d..df59778065 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -175,6 +175,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + Instance, PipelineCache, PipelineLayout, QuerySet, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 0ba8bef8d0..f26b6925cc 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -268,9 +268,9 @@ pub(crate) use dynamic::impl_dyn_resource; pub use dynamic::{ DynAccelerationStructure, DynAcquiredSurfaceTexture, DynAdapter, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandBuffer, DynCommandEncoder, DynComputePipeline, - DynDevice, DynFence, DynOpenDevice, DynPipelineCache, DynPipelineLayout, DynQuerySet, DynQueue, - DynRenderPipeline, DynResource, DynSampler, DynShaderModule, DynSurface, DynSurfaceTexture, - DynTexture, DynTextureView, + DynDevice, DynExposedAdapter, DynFence, DynInstance, DynOpenDevice, DynPipelineCache, + DynPipelineLayout, DynQuerySet, DynQueue, DynRenderPipeline, DynResource, DynSampler, + DynShaderModule, DynSurface, DynSurfaceTexture, DynTexture, DynTextureView, }; use std::{ @@ -392,7 +392,7 @@ impl InstanceError { } pub trait Api: Clone + fmt::Debug + Sized { - type Instance: Instance; + type Instance: DynInstance + Instance; type Surface: DynSurface + Surface; type Adapter: DynAdapter + Adapter; type Device: DynDevice + Device; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 728ee8f496..62d409a8ff 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -82,6 +82,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + Instance, PipelineCache, PipelineLayout, QuerySet, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 90c2cf2a0c..0b024b80a7 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -89,6 +89,7 @@ crate::impl_dyn_resource!( ComputePipeline, Device, Fence, + Instance, PipelineCache, PipelineLayout, QuerySet, From 6e10de7f2e01a756fd913c8c1020776c8308e82e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 11 Jul 2024 00:35:36 +0200 Subject: [PATCH 44/53] The big unraveling: core device now has a boxed `DynDevice`, ripple effects from there leading to boxing of almost all hal resources --- wgpu-core/src/binding_model.rs | 20 ++-- wgpu-core/src/command/allocator.rs | 18 ++-- wgpu-core/src/command/bundle.rs | 6 +- wgpu-core/src/command/clear.rs | 32 +++--- wgpu-core/src/command/compute.rs | 67 ++++++------ wgpu-core/src/command/memory_init.rs | 12 +-- wgpu-core/src/command/mod.rs | 60 ++++++----- wgpu-core/src/command/query.rs | 16 ++- wgpu-core/src/command/render.rs | 17 ++- wgpu-core/src/command/transfer.rs | 115 ++++++++++++--------- wgpu-core/src/device/global.rs | 14 ++- wgpu-core/src/device/life.rs | 4 +- wgpu-core/src/device/mod.rs | 10 +- wgpu-core/src/device/queue.rs | 110 +++++++++++--------- wgpu-core/src/device/resource.rs | 95 ++++++++--------- wgpu-core/src/hub.rs | 3 +- wgpu-core/src/instance.rs | 6 +- wgpu-core/src/pipeline.rs | 28 +++-- wgpu-core/src/present.rs | 15 ++- wgpu-core/src/resource.rs | 148 ++++++++++++++------------- wgpu-core/src/track/buffer.rs | 4 +- wgpu-core/src/track/mod.rs | 8 +- wgpu-core/src/track/texture.rs | 6 +- wgpu/src/backend/wgpu_core.rs | 2 +- 24 files changed, 419 insertions(+), 397 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 0687e6e0f0..825a96418c 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -499,7 +499,7 @@ impl std::fmt::Display for ExclusivePipeline { /// Bind group layout. #[derive(Debug)] pub struct BindGroupLayout { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, pub(crate) entries: bgl::EntryMap, /// It is very important that we know if the bind group comes from the BGL pool. @@ -525,7 +525,6 @@ impl Drop for BindGroupLayout { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_bind_group_layout(raw); } } @@ -537,8 +536,8 @@ crate::impl_parent_device!(BindGroupLayout); crate::impl_storage_item!(BindGroupLayout); impl BindGroupLayout { - pub(crate) fn raw(&self) -> &A::BindGroupLayout { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout { + self.raw.as_ref() } } @@ -652,7 +651,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> { #[derive(Debug)] pub struct PipelineLayout { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -666,15 +665,14 @@ impl Drop for PipelineLayout { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_pipeline_layout(raw); } } } impl PipelineLayout { - pub(crate) fn raw(&self) -> &A::PipelineLayout { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout { + self.raw.as_ref() } pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> { @@ -889,7 +887,7 @@ pub(crate) fn buffer_binding_type_alignment( #[derive(Debug)] pub struct BindGroup { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, pub(crate) device: Arc>, pub(crate) layout: Arc>, /// The `label` from the descriptor used to create the resource. @@ -909,7 +907,6 @@ impl Drop for BindGroup { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_bind_group(raw); } } @@ -920,7 +917,7 @@ impl BindGroup { pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::BindGroup, DestroyedResourceError> { + ) -> Result<&dyn hal::DynBindGroup, DestroyedResourceError> { // Clippy insist on writing it this way. The idea is to return None // if any of the raw buffer is not valid anymore. for buffer in &self.used_buffer_ranges { @@ -932,6 +929,7 @@ impl BindGroup { self.raw .get(guard) + .map(|raw| raw.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } diff --git a/wgpu-core/src/command/allocator.rs b/wgpu-core/src/command/allocator.rs index e17fd08d76..b05898a577 100644 --- a/wgpu-core/src/command/allocator.rs +++ b/wgpu-core/src/command/allocator.rs @@ -1,6 +1,4 @@ -use crate::hal_api::HalApi; use crate::resource_log; -use hal::Device as _; use crate::lock::{rank, Mutex}; @@ -14,11 +12,11 @@ use crate::lock::{rank, Mutex}; /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [ce]: hal::CommandEncoder /// [cb]: hal::Api::CommandBuffer -pub(crate) struct CommandAllocator { - free_encoders: Mutex>, +pub(crate) struct CommandAllocator { + free_encoders: Mutex>>, } -impl CommandAllocator { +impl CommandAllocator { pub(crate) fn new() -> Self { Self { free_encoders: Mutex::new(rank::COMMAND_ALLOCATOR_FREE_ENCODERS, Vec::new()), @@ -33,9 +31,9 @@ impl CommandAllocator { /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub(crate) fn acquire_encoder( &self, - device: &A::Device, - queue: &A::Queue, - ) -> Result { + device: &dyn hal::DynDevice, + queue: &dyn hal::DynQueue, + ) -> Result, hal::DeviceError> { let mut free_encoders = self.free_encoders.lock(); match free_encoders.pop() { Some(encoder) => Ok(encoder), @@ -47,7 +45,7 @@ impl CommandAllocator { } /// Add `encoder` back to the free pool. - pub(crate) fn release_encoder(&self, encoder: A::CommandEncoder) { + pub(crate) fn release_encoder(&self, encoder: Box) { let mut free_encoders = self.free_encoders.lock(); free_encoders.push(encoder); } @@ -55,7 +53,7 @@ impl CommandAllocator { /// Free the pool of command encoders. /// /// This is only called when the `Device` is dropped. - pub(crate) fn dispose(&self, device: &A::Device) { + pub(crate) fn dispose(&self, device: &dyn hal::DynDevice) { let mut free_encoders = self.free_encoders.lock(); resource_log!("CommandAllocator::dispose encoders {}", free_encoders.len()); for cmd_encoder in free_encoders.drain(..) { diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 542c52b886..2f040e615b 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -104,8 +104,6 @@ use arrayvec::ArrayVec; use std::{borrow::Cow, mem, num::NonZeroU32, ops::Range, sync::Arc}; use thiserror::Error; -use hal::CommandEncoder as _; - use super::{ render_command::{ArcRenderCommand, RenderCommand}, DrawKind, @@ -965,7 +963,7 @@ impl RenderBundle { /// The only failure condition is if some of the used buffers are destroyed. pub(super) unsafe fn execute( &self, - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, ) -> Result<(), ExecutionError> { let mut offsets = self.base.dynamic_offsets.as_slice(); @@ -1006,7 +1004,7 @@ impl RenderBundle { offset, size, } => { - let buffer: &A::Buffer = buffer.try_raw(snatch_guard)?; + let buffer = buffer.try_raw(snatch_guard)?; let bb = hal::BufferBinding { buffer, offset: *offset, diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index a93fe8345d..487bdf756b 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -19,7 +19,6 @@ use crate::{ track::{TextureSelector, TextureTrackerSetSingle}, }; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{math::align_to, BufferAddress, BufferUsages, ImageSubresourceRange, TextureAspect}; @@ -167,7 +166,7 @@ impl Global { let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.into_iter()); + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); } Ok(()) @@ -263,7 +262,7 @@ impl Global { encoder, &mut tracker.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &snatch_guard, ) } @@ -272,10 +271,10 @@ impl Global { pub(crate) fn clear_texture>( dst_texture: &Arc>, range: TextureInitRange, - encoder: &mut A::CommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, texture_tracker: &mut T, alignments: &hal::Alignments, - zero_buffer: &A::Buffer, + zero_buffer: &dyn hal::DynBuffer, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), ClearError> { let dst_raw = dst_texture.try_raw(snatch_guard)?; @@ -316,14 +315,15 @@ pub(crate) fn clear_texture>( // change_replace_tracked whenever possible. let dst_barrier = texture_tracker .set_single(dst_texture, selector, clear_usage) - .map(|pending| pending.into_hal(dst_raw)); + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); unsafe { - encoder.transition_textures(dst_barrier.into_iter()); + encoder.transition_textures(&dst_barrier); } // Record actual clearing match dst_texture.clear_mode { - TextureClearMode::BufferCopy => clear_texture_via_buffer_copies::( + TextureClearMode::BufferCopy => clear_texture_via_buffer_copies( &dst_texture.desc, alignments, zero_buffer, @@ -346,13 +346,13 @@ pub(crate) fn clear_texture>( Ok(()) } -fn clear_texture_via_buffer_copies( +fn clear_texture_via_buffer_copies( texture_desc: &wgt::TextureDescriptor<(), Vec>, alignments: &hal::Alignments, - zero_buffer: &A::Buffer, // Buffer of size device::ZERO_BUFFER_SIZE + zero_buffer: &dyn hal::DynBuffer, // Buffer of size device::ZERO_BUFFER_SIZE range: TextureInitRange, - encoder: &mut A::CommandEncoder, - dst_raw: &A::Texture, + encoder: &mut dyn hal::DynCommandEncoder, + dst_raw: &dyn hal::DynTexture, ) { assert!(!texture_desc.format.is_depth_stencil_format()); @@ -436,7 +436,7 @@ fn clear_texture_via_buffer_copies( } unsafe { - encoder.copy_buffer_to_texture(zero_buffer, dst_raw, zero_buffer_copy_regions.into_iter()); + encoder.copy_buffer_to_texture(zero_buffer, dst_raw, &zero_buffer_copy_regions); } } @@ -444,7 +444,7 @@ fn clear_texture_via_render_passes( dst_texture: &Texture, range: TextureInitRange, is_color: bool, - encoder: &mut A::CommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, ) { assert_eq!(dst_texture.desc.dimension, wgt::TextureDimension::D2); @@ -461,7 +461,7 @@ fn clear_texture_via_render_passes( let (color_attachments, depth_stencil_attachment) = if is_color { color_attachments_tmp = [Some(hal::ColorAttachment { target: hal::Attachment { - view: Texture::get_clear_view( + view: Texture::::get_clear_view( &dst_texture.clear_mode, &dst_texture.desc, mip_level, @@ -479,7 +479,7 @@ fn clear_texture_via_render_passes( &[][..], Some(hal::DepthStencilAttachment { target: hal::Attachment { - view: Texture::get_clear_view( + view: Texture::::get_clear_view( &dst_texture.clear_mode, &dst_texture.desc, mip_level, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c31db544d1..a23370527f 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -26,8 +26,6 @@ use crate::{ Label, }; -use hal::CommandEncoder as _; - use thiserror::Error; use wgt::{BufferAddress, DynamicOffset}; @@ -212,7 +210,7 @@ struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { device: &'cmd_buf Arc>, - raw_encoder: &'raw_encoder mut A::CommandEncoder, + raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, tracker: &'cmd_buf mut Tracker, buffer_memory_init_actions: &'cmd_buf mut Vec>, @@ -485,40 +483,41 @@ impl Global { state.tracker.buffers.set_size(indices.buffers.size()); state.tracker.textures.set_size(indices.textures.size()); - let timestamp_writes = if let Some(tw) = timestamp_writes.take() { - tw.query_set - .same_device_as(cmd_buf) - .map_pass_err(pass_scope)?; - - let query_set = state.tracker.query_sets.insert_single(tw.query_set); + let timestamp_writes: Option> = + if let Some(tw) = timestamp_writes.take() { + tw.query_set + .same_device_as(cmd_buf) + .map_pass_err(pass_scope)?; + + let query_set = state.tracker.query_sets.insert_single(tw.query_set); + + // 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) + 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 { - tw.beginning_of_pass_write_index - .or(tw.end_of_pass_write_index) - .map(|i| i..i + 1) + None }; - // 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 - }; let hal_desc = hal::ComputePassDescriptor { label: hal_label(base.label.as_deref(), self.instance.flags), diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 96427eacc7..7e672393f1 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -1,7 +1,5 @@ use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain}; -use hal::CommandEncoder; - use crate::{ device::Device, hal_api::HalApi, @@ -140,7 +138,7 @@ pub(crate) fn fixup_discarded_surfaces< InitIter: Iterator>, >( inits: InitIter, - encoder: &mut A::CommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, texture_tracker: &mut TextureTracker, device: &Device, snatch_guard: &SnatchGuard<'_>, @@ -155,7 +153,7 @@ pub(crate) fn fixup_discarded_surfaces< encoder, texture_tracker, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), snatch_guard, ) .unwrap(); @@ -233,7 +231,7 @@ impl BakedCommands { self.encoder.transition_buffers( transition .map(|pending| pending.into_hal(&buffer, snatch_guard)) - .into_iter(), + .as_slice(), ); } @@ -307,10 +305,10 @@ impl BakedCommands { let clear_result = clear_texture( &texture_use.texture, range, - &mut self.encoder, + self.encoder.as_mut(), &mut device_tracker.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), snatch_guard, ); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 7314e8f04c..d16e7f6d05 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -39,7 +39,6 @@ use crate::track::{DeviceTracker, Tracker, UsageScope}; use crate::LabelHelpers; use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label}; -use hal::CommandEncoder as _; use thiserror::Error; #[cfg(feature = "trace")] @@ -115,7 +114,7 @@ pub(crate) enum CommandEncoderStatus { /// [rce]: hal::Api::CommandEncoder /// [rcb]: hal::Api::CommandBuffer /// [`CommandEncoderId`]: crate::id::CommandEncoderId -pub(crate) struct CommandEncoder { +pub(crate) struct CommandEncoder { /// The underlying `wgpu_hal` [`CommandEncoder`]. /// /// Successfully executed command buffers' encoders are saved in a @@ -123,7 +122,7 @@ pub(crate) struct CommandEncoder { /// /// [`CommandEncoder`]: hal::Api::CommandEncoder /// [`CommandAllocator`]: crate::command::CommandAllocator - raw: A::CommandEncoder, + raw: Box, /// All the raw command buffers for our owning [`CommandBuffer`], in /// submission order. @@ -136,7 +135,7 @@ pub(crate) struct CommandEncoder { /// /// [CE::ra]: hal::CommandEncoder::reset_all /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder - list: Vec, + list: Vec>, /// True if `raw` is in the "recording" state. /// @@ -150,7 +149,7 @@ pub(crate) struct CommandEncoder { } //TODO: handle errors better -impl CommandEncoder { +impl CommandEncoder { /// Finish the current command buffer, if any, and place it /// at the second-to-last position in our list. /// @@ -219,14 +218,14 @@ impl CommandEncoder { /// Begin recording a new command buffer, if we haven't already. /// /// The underlying hal encoder is put in the "recording" state. - pub(crate) fn open(&mut self) -> Result<&mut A::CommandEncoder, DeviceError> { + pub(crate) fn open(&mut self) -> Result<&mut dyn hal::DynCommandEncoder, DeviceError> { if !self.is_open { self.is_open = true; let hal_label = self.hal_label.as_deref(); unsafe { self.raw.begin_encoding(hal_label)? }; } - Ok(&mut self.raw) + Ok(self.raw.as_mut()) } /// Begin recording a new command buffer for a render pass, with @@ -242,8 +241,8 @@ impl CommandEncoder { } pub(crate) struct BakedCommands { - pub(crate) encoder: A::CommandEncoder, - pub(crate) list: Vec, + pub(crate) encoder: Box, + pub(crate) list: Vec>, pub(crate) trackers: Tracker, buffer_memory_init_actions: Vec>, texture_memory_actions: CommandBufferTextureMemoryActions, @@ -255,7 +254,7 @@ pub struct CommandBufferMutable { /// they belong to. /// /// [`wgpu_hal::Api::CommandBuffer`]: hal::Api::CommandBuffer - pub(crate) encoder: CommandEncoder, + pub(crate) encoder: CommandEncoder, /// The current state of this command buffer's encoder. status: CommandEncoderStatus, @@ -280,7 +279,7 @@ pub struct CommandBufferMutable { impl CommandBufferMutable { pub(crate) fn open_encoder_and_tracker( &mut self, - ) -> Result<(&mut A::CommandEncoder, &mut Tracker), DeviceError> { + ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { let encoder = self.encoder.open()?; let tracker = &mut self.trackers; @@ -329,17 +328,20 @@ impl Drop for CommandBuffer { } let mut baked = self.extract_baked_commands(); unsafe { - baked.encoder.reset_all(baked.list.into_iter()); + baked.encoder.reset_all(baked.list); } unsafe { - use hal::Device; self.device.raw().destroy_command_encoder(baked.encoder); } } } impl CommandBuffer { - pub(crate) fn new(encoder: A::CommandEncoder, device: &Arc>, label: &Label) -> Self { + pub(crate) fn new( + encoder: Box, + device: &Arc>, + label: &Label, + ) -> Self { CommandBuffer { device: device.clone(), support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE), @@ -370,7 +372,7 @@ impl CommandBuffer { } pub(crate) fn insert_barriers_from_tracker( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, head: &Tracker, snatch_guard: &SnatchGuard, @@ -384,7 +386,7 @@ impl CommandBuffer { } pub(crate) fn insert_barriers_from_scope( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, head: &UsageScope, snatch_guard: &SnatchGuard, @@ -398,27 +400,31 @@ impl CommandBuffer { } pub(crate) fn drain_barriers( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, snatch_guard: &SnatchGuard, ) { profiling::scope!("drain_barriers"); - let buffer_barriers = base.buffers.drain_transitions(snatch_guard); + let buffer_barriers = base + .buffers + .drain_transitions(snatch_guard) + .collect::>(); let (transitions, textures) = base.textures.drain_transitions(snatch_guard); let texture_barriers = transitions .into_iter() .enumerate() - .map(|(i, p)| p.into_hal(textures[i].unwrap().raw())); + .map(|(i, p)| p.into_hal(textures[i].unwrap().raw())) + .collect::>(); unsafe { - raw.transition_buffers(buffer_barriers); - raw.transition_textures(texture_barriers); + raw.transition_buffers(&buffer_barriers); + raw.transition_textures(&texture_barriers); } } pub(crate) fn insert_barriers_from_device_tracker( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut DeviceTracker, head: &Tracker, snatch_guard: &SnatchGuard, @@ -427,15 +433,17 @@ impl CommandBuffer { let buffer_barriers = base .buffers - .set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard); + .set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard) + .collect::>(); let texture_barriers = base .textures - .set_from_tracker_and_drain_transitions(&head.textures, snatch_guard); + .set_from_tracker_and_drain_transitions(&head.textures, snatch_guard) + .collect::>(); unsafe { - raw.transition_buffers(buffer_barriers); - raw.transition_textures(texture_barriers); + raw.transition_buffers(&buffer_barriers); + raw.transition_textures(&texture_barriers); } } } diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index 382fa2d296..26997ebd8b 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -1,5 +1,3 @@ -use hal::CommandEncoder as _; - #[cfg(feature = "trace")] use crate::device::trace::Command as TraceCommand; use crate::{ @@ -44,7 +42,7 @@ impl QueryResetMap { std::mem::replace(&mut vec_pair.0[query as usize], true) } - pub fn reset_queries(&mut self, raw_encoder: &mut A::CommandEncoder) { + pub fn reset_queries(&mut self, raw_encoder: &mut dyn hal::DynCommandEncoder) { for (_, (state, query_set)) in self.map.drain() { debug_assert_eq!(state.len(), query_set.desc.count as usize); @@ -199,7 +197,7 @@ impl QuerySet { pub(super) fn validate_and_write_timestamp( self: &Arc, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, query_index: u32, reset_state: Option<&mut QueryResetMap>, ) -> Result<(), QueryUseError> { @@ -220,7 +218,7 @@ impl QuerySet { pub(super) fn validate_and_begin_occlusion_query( query_set: Arc>, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker>, query_index: u32, reset_state: Option<&mut QueryResetMap>, @@ -251,7 +249,7 @@ pub(super) fn validate_and_begin_occlusion_query( } pub(super) fn end_occlusion_query( - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, active_query: &mut Option<(Arc>, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { @@ -264,7 +262,7 @@ pub(super) fn end_occlusion_query( pub(super) fn validate_and_begin_pipeline_statistics_query( query_set: Arc>, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker>, cmd_buf: &CommandBuffer, query_index: u32, @@ -302,7 +300,7 @@ pub(super) fn validate_and_begin_pipeline_statistics_query( } pub(super) fn end_pipeline_statistics_query( - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, active_query: &mut Option<(Arc>, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { @@ -477,7 +475,7 @@ impl Global { let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; unsafe { - raw_encoder.transition_buffers(dst_barrier.into_iter()); + raw_encoder.transition_buffers(dst_barrier.as_slice()); raw_encoder.copy_query_results( query_set.raw(), start_query..end_query, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 73ce837ba9..7e7f9a1af8 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -34,7 +34,6 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{ BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages, @@ -461,7 +460,7 @@ struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { device: &'cmd_buf Arc>, - raw_encoder: &'raw_encoder mut A::CommandEncoder, + raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, tracker: &'cmd_buf mut Tracker, buffer_memory_init_actions: &'cmd_buf mut Vec>, @@ -826,7 +825,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { mut depth_stencil_attachment: Option>, mut timestamp_writes: Option>, mut occlusion_query_set: Option>>, - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, pending_query_resets: &mut QueryResetMap, @@ -1255,7 +1254,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { fn finish( mut self, - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, ) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState), RenderPassErrorInner> { profiling::scope!("RenderPassInfo::finish"); @@ -1298,7 +1297,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { hal::AttachmentOps::STORE, // clear depth ) }; - let desc = hal::RenderPassDescriptor { + let desc = hal::RenderPassDescriptor::<'_, _, dyn hal::DynTextureView> { label: Some("(wgpu internal) Zero init discarded depth/stencil aspect"), extent: view.render_extent.unwrap(), sample_count: view.samples, @@ -1632,8 +1631,6 @@ impl Global { tracker.buffers.set_size(indices.buffers.size()); tracker.textures.set_size(indices.textures.size()); - let raw = &mut encoder.raw; - let mut state = State { pipeline_flags: PipelineFlags::empty(), binder: Binder::new(), @@ -1649,7 +1646,7 @@ impl Global { snatch_guard, device, - raw_encoder: raw, + raw_encoder: encoder.raw.as_mut(), tracker, buffer_memory_init_actions, texture_memory_actions, @@ -2179,7 +2176,7 @@ fn set_index_buffer( size, }; unsafe { - state.raw_encoder.set_index_buffer(bb, index_format); + hal::DynCommandEncoder::set_index_buffer(state.raw_encoder, bb, index_format); } Ok(()) } @@ -2244,7 +2241,7 @@ fn set_vertex_buffer( size, }; unsafe { - state.raw_encoder.set_vertex_buffer(slot, bb); + hal::DynCommandEncoder::set_vertex_buffer(state.raw_encoder, slot, bb); } state.vertex.update_limits(); Ok(()) diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index b8208f5dd0..4ccc762720 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -21,11 +21,10 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; -use std::{iter, sync::Arc}; +use std::sync::Arc; use super::{memory_init::CommandBufferTextureMemoryActions, ClearError, CommandEncoder}; @@ -410,7 +409,7 @@ pub(crate) fn validate_texture_copy_range( fn handle_texture_init( init_kind: MemoryInitKind, - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, @@ -445,7 +444,7 @@ fn handle_texture_init( cmd_buf_raw, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), snatch_guard, )?; } @@ -459,7 +458,7 @@ fn handle_texture_init( /// Ensure the source texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_src_texture_init( - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, @@ -487,7 +486,7 @@ fn handle_src_texture_init( /// Ensure the destination texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_dst_texture_init( - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, @@ -687,9 +686,13 @@ impl Global { size: wgt::BufferSize::new(size).unwrap(), }; let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let barriers = src_barrier + .into_iter() + .chain(dst_barrier) + .collect::>(); unsafe { - cmd_buf_raw.transition_buffers(src_barrier.into_iter().chain(dst_barrier)); - cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, iter::once(region)); + cmd_buf_raw.transition_buffers(&barriers); + cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); } Ok(()) } @@ -801,7 +804,9 @@ impl Global { dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; - let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_raw)); + let dst_barrier = dst_pending + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); if !dst_base.aspect.is_one() { return Err(TransferError::CopyAspectNotOne.into()); @@ -837,23 +842,25 @@ impl Global { MemoryInitKind::NeedsInitializedMemory, )); - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut texture_base = dst_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = source.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = dst_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = source.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(dst_barrier.into_iter()); - cmd_buf_raw.transition_buffers(src_barrier.into_iter()); - cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, regions); + cmd_buf_raw.transition_textures(&dst_barrier); + cmd_buf_raw.transition_buffers(src_barrier.as_slice()); + cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); } Ok(()) } @@ -956,7 +963,9 @@ impl Global { } .into()); } - let src_barrier = src_pending.map(|pending| pending.into_hal(src_raw)); + let src_barrier = src_pending + .map(|pending| pending.into_hal(src_raw)) + .collect::>(); let dst_buffer = hub .buffers @@ -1009,26 +1018,28 @@ impl Global { MemoryInitKind::ImplicitlyInitialized, )); - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut texture_base = src_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = destination.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = src_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = destination.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.into_iter()); - cmd_buf_raw.transition_textures(src_barrier.into_iter()); + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); + cmd_buf_raw.transition_textures(&src_barrier); cmd_buf_raw.copy_texture_to_buffer( src_raw, hal::TextureUses::COPY_SRC, dst_raw, - regions, + ®ions, ); } Ok(()) @@ -1186,25 +1197,27 @@ impl Global { height: src_copy_size.height.min(dst_copy_size.height), depth: src_copy_size.depth.min(dst_copy_size.depth), }; - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut src_base = src_tex_base.clone(); - let mut dst_base = dst_tex_base.clone(); - src_base.array_layer += rel_array_layer; - dst_base.array_layer += rel_array_layer; - hal::TextureCopy { - src_base, - dst_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut src_base = src_tex_base.clone(); + let mut dst_base = dst_tex_base.clone(); + src_base.array_layer += rel_array_layer; + dst_base.array_layer += rel_array_layer; + hal::TextureCopy { + src_base, + dst_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(barriers.into_iter()); + cmd_buf_raw.transition_textures(&barriers); cmd_buf_raw.copy_texture_to_texture( src_raw, hal::TextureUses::COPY_SRC, dst_raw, - regions, + ®ions, ); } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 7fd82e8cee..cb9f62ea03 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -24,8 +24,6 @@ use crate::{ Label, }; -use hal::Device as _; - use wgt::{BufferAddress, TextureFormat}; use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering}; @@ -282,10 +280,10 @@ impl Global { .map_err(DeviceError::from)?; std::ptr::copy_nonoverlapping(data.as_ptr(), mapping.ptr.as_ptr(), data.len()); if !mapping.is_coherent { - device.raw().flush_mapped_ranges( - raw_buf, - std::iter::once(offset..offset + data.len() as u64), - ); + #[allow(clippy::single_range_in_vec_init)] + device + .raw() + .flush_mapped_ranges(raw_buf, &[offset..offset + data.len() as u64]); } device.raw().unmap_buffer(raw_buf); } @@ -391,7 +389,7 @@ impl Global { /// - `hal_texture` must be initialized pub unsafe fn create_texture_from_hal( &self, - hal_texture: A::Texture, + hal_texture: Box, device_id: DeviceId, desc: &resource::TextureDescriptor, id_in: Option, @@ -1995,7 +1993,7 @@ impl Global { match unsafe { A::surface_as_hal(surface) .unwrap() - .configure(device.raw(), &hal_config) + .configure(device.raw().as_any().downcast_ref().unwrap(), &hal_config) } { Ok(()) => (), Err(error) => { diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 7408c184dc..1ee84be933 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -268,7 +268,7 @@ impl LifetimeTracker { pub fn triage_submissions( &mut self, last_done: SubmissionIndex, - command_allocator: &crate::command::CommandAllocator, + command_allocator: &crate::command::CommandAllocator, ) -> SmallVec<[SubmittedWorkDoneClosure; 1]> { profiling::scope!("triage_submissions"); @@ -351,7 +351,7 @@ impl LifetimeTracker { #[must_use] pub(crate) fn handle_mapping( &mut self, - raw: &A::Device, + raw: &dyn hal::DynDevice, snatch_guard: &SnatchGuard, ) -> Vec { if self.ready_to_map.is_empty() { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 1f890de902..c6f88b2634 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -12,13 +12,12 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::Device as _; use smallvec::SmallVec; use std::os::raw::c_char; use thiserror::Error; use wgt::{BufferAddress, DeviceLostReason, TextureFormat}; -use std::{iter, num::NonZeroU32}; +use std::num::NonZeroU32; pub mod any_device; pub(crate) mod bgl; @@ -301,7 +300,7 @@ impl DeviceLostClosure { } fn map_buffer( - raw: &A::Device, + raw: &dyn hal::DynDevice, buffer: &Buffer, offset: BufferAddress, size: BufferAddress, @@ -315,8 +314,9 @@ fn map_buffer( }; if !mapping.is_coherent && kind == HostMap::Read { + #[allow(clippy::single_range_in_vec_init)] unsafe { - raw.invalidate_mapped_ranges(raw_buffer, iter::once(offset..offset + size)); + raw.invalidate_mapped_ranges(raw_buffer, &[offset..offset + size]); } } @@ -350,7 +350,7 @@ fn map_buffer( mapped[fill_range].fill(0); if !mapping.is_coherent && kind == HostMap::Read { - unsafe { raw.flush_mapped_ranges(raw_buffer, iter::once(uninitialized)) }; + unsafe { raw.flush_mapped_ranges(raw_buffer, &[uninitialized]) }; } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 27f13e2f46..fbcbbdcbed 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -25,7 +25,6 @@ use crate::{ FastHashMap, SubmissionIndex, }; -use hal::{CommandEncoder as _, Device as _, Queue as _}; use smallvec::SmallVec; use std::{ @@ -39,20 +38,20 @@ use thiserror::Error; use super::Device; pub struct Queue { - raw: ManuallyDrop, + raw: ManuallyDrop>, pub(crate) device: Arc>, } impl Queue { - pub(crate) fn new(device: Arc>, raw: A::Queue) -> Self { + pub(crate) fn new(device: Arc>, raw: Box) -> Self { Queue { raw: ManuallyDrop::new(raw), device, } } - pub(crate) fn raw(&self) -> &A::Queue { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynQueue { + self.raw.as_ref() } } @@ -154,8 +153,8 @@ pub enum TempResource { /// [`CommandBuffer`]: hal::Api::CommandBuffer /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub(crate) struct EncoderInFlight { - raw: A::CommandEncoder, - cmd_buffers: Vec, + raw: Box, + cmd_buffers: Vec>, pub(crate) trackers: Tracker, /// These are the buffers that have been tracked by `PendingWrites`. @@ -169,8 +168,8 @@ impl EncoderInFlight { /// /// Return the command encoder, fully reset and ready to be /// reused. - pub(crate) unsafe fn land(mut self) -> A::CommandEncoder { - unsafe { self.raw.reset_all(self.cmd_buffers.into_iter()) }; + pub(crate) unsafe fn land(mut self) -> Box { + unsafe { self.raw.reset_all(self.cmd_buffers) }; { // This involves actually decrementing the ref count of all command buffer // resources, so can be _very_ expensive. @@ -205,7 +204,7 @@ impl EncoderInFlight { /// All uses of [`StagingBuffer`]s end up here. #[derive(Debug)] pub(crate) struct PendingWrites { - pub command_encoder: A::CommandEncoder, + pub command_encoder: Box, /// True if `command_encoder` is in the "recording" state, as /// described in the docs for the [`wgpu_hal::CommandEncoder`] @@ -220,7 +219,7 @@ pub(crate) struct PendingWrites { } impl PendingWrites { - pub fn new(command_encoder: A::CommandEncoder) -> Self { + pub fn new(command_encoder: Box) -> Self { Self { command_encoder, is_recording: false, @@ -230,7 +229,7 @@ impl PendingWrites { } } - pub fn dispose(mut self, device: &A::Device) { + pub fn dispose(mut self, device: &dyn hal::DynDevice) { unsafe { if self.is_recording { self.command_encoder.discard_encoding(); @@ -270,9 +269,9 @@ impl PendingWrites { fn pre_submit( &mut self, - command_allocator: &CommandAllocator, - device: &A::Device, - queue: &A::Queue, + command_allocator: &CommandAllocator, + device: &dyn hal::DynDevice, + queue: &dyn hal::DynQueue, ) -> Result>, DeviceError> { if self.is_recording { let pending_buffers = mem::take(&mut self.dst_buffers); @@ -298,7 +297,7 @@ impl PendingWrites { } } - pub fn activate(&mut self) -> &mut A::CommandEncoder { + pub fn activate(&mut self) -> &mut dyn hal::DynCommandEncoder { if !self.is_recording { unsafe { self.command_encoder @@ -307,7 +306,7 @@ impl PendingWrites { } self.is_recording = true; } - &mut self.command_encoder + self.command_encoder.as_mut() } pub fn deactivate(&mut self) { @@ -586,11 +585,12 @@ impl Global { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }) - .chain(transition.map(|pending| pending.into_hal(&dst, &snatch_guard))); + .chain(transition.map(|pending| pending.into_hal(&dst, &snatch_guard))) + .collect::>(); let encoder = pending_writes.activate(); unsafe { - encoder.transition_buffers(barriers); - encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, iter::once(region)); + encoder.transition_buffers(&barriers); + encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, &[region]); } pending_writes.insert_buffer(&dst); @@ -723,7 +723,7 @@ impl Global { encoder, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &device.snatchable_lock.read(), ) .map_err(QueueWriteError::from)?; @@ -802,24 +802,26 @@ impl Global { let staging_buffer = staging_buffer.flush(); - let regions = (0..array_layer_count).map(|array_layer_offset| { - let mut texture_base = dst_base.clone(); - texture_base.array_layer += array_layer_offset; - hal::BufferTextureCopy { - buffer_layout: wgt::ImageDataLayout { - offset: array_layer_offset as u64 - * rows_per_image as u64 - * stage_bytes_per_row as u64, - bytes_per_row: Some(stage_bytes_per_row), - rows_per_image: Some(rows_per_image), - }, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|array_layer_offset| { + let mut texture_base = dst_base.clone(); + texture_base.array_layer += array_layer_offset; + hal::BufferTextureCopy { + buffer_layout: wgt::ImageDataLayout { + offset: array_layer_offset as u64 + * rows_per_image as u64 + * stage_bytes_per_row as u64, + bytes_per_row: Some(stage_bytes_per_row), + rows_per_image: Some(rows_per_image), + }, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); { - let barrier = hal::BufferBarrier { + let buffer_barrier = hal::BufferBarrier { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }; @@ -829,10 +831,14 @@ impl Global { trackers .textures .set_single(&dst, selector, hal::TextureUses::COPY_DST); + let texture_barriers = transition + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); + unsafe { - encoder.transition_textures(transition.map(|pending| pending.into_hal(dst_raw))); - encoder.transition_buffers(iter::once(barrier)); - encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, regions); + encoder.transition_textures(&texture_barriers); + encoder.transition_buffers(&[buffer_barrier]); + encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, ®ions); } } @@ -990,7 +996,7 @@ impl Global { encoder, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &device.snatchable_lock.read(), ) .map_err(QueueWriteError::from)?; @@ -1185,7 +1191,7 @@ impl Global { //Note: stateless trackers are not merged: // device already knows these resources exist. CommandBuffer::insert_barriers_from_device_tracker( - &mut baked.encoder, + baked.encoder.as_mut(), &mut *trackers, &baked.trackers, &snatch_guard, @@ -1212,9 +1218,10 @@ impl Global { .set_from_usage_scope_and_drain_transitions( &used_surface_textures, &snatch_guard, - ); + ) + .collect::>(); let present = unsafe { - baked.encoder.transition_textures(texture_barriers); + baked.encoder.transition_textures(&texture_barriers); baked.encoder.end_encoding().unwrap() }; baked.list.push(present); @@ -1262,11 +1269,12 @@ impl Global { .set_from_usage_scope_and_drain_transitions( &used_surface_textures, &snatch_guard, - ); + ) + .collect::>(); unsafe { pending_writes .command_encoder - .transition_textures(texture_barriers); + .transition_textures(&texture_barriers); }; } } @@ -1279,16 +1287,18 @@ impl Global { let hal_command_buffers = active_executions .iter() - .flat_map(|e| e.cmd_buffers.iter()) + .flat_map(|e| e.cmd_buffers.iter().map(|b| b.as_ref())) .collect::>(); { let mut submit_surface_textures = - SmallVec::<[_; 2]>::with_capacity(submit_surface_textures_owned.len()); + SmallVec::<[&dyn hal::DynSurfaceTexture; 2]>::with_capacity( + submit_surface_textures_owned.len(), + ); for texture in submit_surface_textures_owned.values() { let raw = match texture.inner.get(&snatch_guard) { - Some(TextureInner::Surface { raw, .. }) => raw, + Some(TextureInner::Surface { raw, .. }) => raw.as_ref(), _ => unreachable!(), }; submit_surface_textures.push(raw); @@ -1300,7 +1310,7 @@ impl Global { .submit( &hal_command_buffers, &submit_surface_textures, - (&mut fence, submit_index), + (fence.as_mut(), submit_index), ) .map_err(DeviceError::from)?; } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 104f54a40a..7801ccd059 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -36,7 +36,6 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::{CommandEncoder as _, Device as _}; use once_cell::sync::OnceCell; use smallvec::SmallVec; @@ -45,7 +44,6 @@ use wgt::{DeviceLostReason, TextureFormat, TextureSampleType, TextureViewDimensi use std::{ borrow::Cow, - iter, mem::ManuallyDrop, num::NonZeroU32, sync::{ @@ -80,15 +78,15 @@ use super::{ /// When locking pending_writes please check that trackers is not locked /// trackers should be locked only when needed for the shortest time possible pub struct Device { - raw: ManuallyDrop, + raw: ManuallyDrop>, pub(crate) adapter: Arc>, pub(crate) queue: OnceCell>>, - queue_to_drop: OnceCell, - pub(crate) zero_buffer: ManuallyDrop, + queue_to_drop: OnceCell>, + pub(crate) zero_buffer: ManuallyDrop>, /// The `label` from the descriptor used to create the resource. label: String, - pub(crate) command_allocator: command::CommandAllocator, + pub(crate) command_allocator: command::CommandAllocator, /// The index of the last command submission that was attempted. /// @@ -112,7 +110,7 @@ pub struct Device { // NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the // `fence` lock to avoid deadlocks. - pub(crate) fence: RwLock>, + pub(crate) fence: RwLock>>, pub(crate) snatchable_lock: SnatchLock, /// Is this device valid? Valid is closely associated with "lose the device", @@ -177,8 +175,8 @@ impl Drop for Device { let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; // SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point. let fence = unsafe { ManuallyDrop::take(&mut self.fence.write()) }; - pending_writes.dispose(&raw); - self.command_allocator.dispose(&raw); + pending_writes.dispose(raw.as_ref()); + self.command_allocator.dispose(raw.as_ref()); unsafe { raw.destroy_buffer(zero_buffer); raw.destroy_fence(fence); @@ -197,8 +195,8 @@ pub enum CreateDeviceError { } impl Device { - pub(crate) fn raw(&self) -> &A::Device { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynDevice { + self.raw.as_ref() } pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> { if self.features.contains(feature) { @@ -222,8 +220,8 @@ impl Device { impl Device { pub(crate) fn new( - raw_device: A::Device, - raw_queue: &A::Queue, + raw_device: Box, + raw_queue: &dyn hal::DynQueue, adapter: &Arc>, desc: &DeviceDescriptor, trace_path: Option<&std::path::Path>, @@ -238,7 +236,7 @@ impl Device { let command_allocator = command::CommandAllocator::new(); let pending_encoder = command_allocator - .acquire_encoder(&raw_device, raw_queue) + .acquire_encoder(raw_device.as_ref(), raw_queue) .map_err(|_| CreateDeviceError::OutOfMemory)?; let mut pending_writes = PendingWrites::::new(pending_encoder); @@ -257,19 +255,19 @@ impl Device { unsafe { pending_writes .command_encoder - .transition_buffers(iter::once(hal::BufferBarrier { - buffer: &zero_buffer, + .transition_buffers(&[hal::BufferBarrier { + buffer: zero_buffer.as_ref(), usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, - })); + }]); pending_writes .command_encoder - .clear_buffer(&zero_buffer, 0..ZERO_BUFFER_SIZE); + .clear_buffer(zero_buffer.as_ref(), 0..ZERO_BUFFER_SIZE); pending_writes .command_encoder - .transition_buffers(iter::once(hal::BufferBarrier { - buffer: &zero_buffer, + .transition_buffers(&[hal::BufferBarrier { + buffer: zero_buffer.as_ref(), usage: hal::BufferUses::COPY_DST..hal::BufferUses::COPY_SRC, - })); + }]); } let alignments = adapter.raw.capabilities.alignments.clone(); @@ -335,7 +333,7 @@ impl Device { } } - pub(crate) fn release_queue(&self, queue: A::Queue) { + pub(crate) fn release_queue(&self, queue: Box) { assert!(self.queue_to_drop.set(queue).is_ok()); } @@ -364,7 +362,6 @@ impl Device { resource_log!("Destroy raw {}", view.error_ident()); unsafe { - use hal::Device; self.raw().destroy_texture_view(raw_view); } } @@ -380,7 +377,6 @@ impl Device { resource_log!("Destroy raw {}", bind_group.error_ident()); unsafe { - use hal::Device; self.raw().destroy_bind_group(raw_bind_group); } } @@ -411,7 +407,7 @@ impl Device { /// return it to our callers.) pub(crate) fn maintain<'this>( &'this self, - fence: crate::lock::RwLockReadGuard>, + fence: crate::lock::RwLockReadGuard>>, maintain: wgt::Maintain, snatch_guard: SnatchGuard, ) -> Result<(UserClosures, bool), WaitIdleError> { @@ -440,7 +436,7 @@ impl Device { .load(Ordering::Acquire), wgt::Maintain::Poll => unsafe { self.raw() - .get_fence_value(&fence) + .get_fence_value(fence.as_ref()) .map_err(DeviceError::from)? }, }; @@ -449,7 +445,7 @@ impl Device { if maintain.is_wait() { unsafe { self.raw() - .wait(&fence, submission_index, CLEANUP_WAIT_MS) + .wait(fence.as_ref(), submission_index, CLEANUP_WAIT_MS) .map_err(DeviceError::from)? }; } @@ -654,7 +650,7 @@ impl Device { pub(crate) fn create_texture_from_hal( self: &Arc, - hal_texture: A::Texture, + hal_texture: Box, desc: &resource::TextureDescriptor, ) -> Result>, resource::CreateTextureError> { let format_features = self @@ -687,7 +683,7 @@ impl Device { desc: &resource::BufferDescriptor, ) -> Arc> { let buffer = Buffer { - raw: Snatchable::new(hal_buffer), + raw: Snatchable::new(Box::new(hal_buffer)), device: self.clone(), usage: desc.usage, size: desc.size, @@ -972,8 +968,10 @@ impl Device { }, }; clear_views.push(ManuallyDrop::new( - unsafe { self.raw().create_texture_view(&raw_texture, &desc) } - .map_err(DeviceError::from)?, + unsafe { + self.raw().create_texture_view(raw_texture.as_ref(), &desc) + } + .map_err(DeviceError::from)?, )); }; } @@ -1889,7 +1887,8 @@ impl Device { used: &mut BindGroupStates, limits: &wgt::Limits, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> + { use crate::binding_model::CreateBindGroupError as Error; let (binding_ty, dynamic, min_size) = match decl.ty { @@ -2021,7 +2020,7 @@ impl Device { binding: u32, decl: &wgt::BindGroupLayoutEntry, sampler: &'a Arc>, - ) -> Result<&'a A::Sampler, binding_model::CreateBindGroupError> { + ) -> Result<&'a dyn hal::DynSampler, binding_model::CreateBindGroupError> { use crate::binding_model::CreateBindGroupError as Error; used.samplers.insert_single(sampler.clone()); @@ -2072,7 +2071,8 @@ impl Device { used: &mut BindGroupStates, used_texture_ranges: &mut Vec>, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> + { view.same_device(self)?; let (pub_usage, internal_use) = self.texture_use_parameters( @@ -2389,14 +2389,14 @@ impl Device { .unwrap(); match (sample_type, compat_sample_type) { (Tst::Uint, Tst::Uint) | - (Tst::Sint, Tst::Sint) | - (Tst::Depth, Tst::Depth) | - // if we expect non-filterable, accept anything float - (Tst::Float { filterable: false }, Tst::Float { .. }) | - // if we expect filterable, require it - (Tst::Float { filterable: true }, Tst::Float { filterable: true }) | - // if we expect non-filterable, also accept depth - (Tst::Float { filterable: false }, Tst::Depth) => {} + (Tst::Sint, Tst::Sint) | + (Tst::Depth, Tst::Depth) | + // if we expect non-filterable, accept anything float + (Tst::Float { filterable: false }, Tst::Float { .. }) | + // if we expect filterable, require it + (Tst::Float { filterable: true }, Tst::Float { filterable: true }) | + // if we expect non-filterable, also accept depth + (Tst::Float { filterable: false }, Tst::Depth) => {} // if we expect filterable, also accept Float that is defined as // unfilterable if filterable feature is explicitly enabled (only hit // if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is @@ -2999,7 +2999,7 @@ impl Device { break; } else { return Err(pipeline::CreateRenderPipelineError - ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); + ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); } } } @@ -3491,9 +3491,9 @@ impl Device { submission_index: crate::SubmissionIndex, ) -> Result<(), DeviceError> { let fence = self.fence.read(); - let last_done_index = unsafe { self.raw().get_fence_value(&fence)? }; + let last_done_index = unsafe { self.raw().get_fence_value(fence.as_ref())? }; if last_done_index < submission_index { - unsafe { self.raw().wait(&fence, submission_index, !0)? }; + unsafe { self.raw().wait(fence.as_ref(), submission_index, !0)? }; drop(fence); let closures = self .lock_life() @@ -3622,7 +3622,7 @@ impl Device { pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer) { let mut baked = cmd_buf.extract_baked_commands(); unsafe { - baked.encoder.reset_all(baked.list.into_iter()); + baked.encoder.reset_all(baked.list); } unsafe { self.raw().destroy_command_encoder(baked.encoder); @@ -3637,7 +3637,8 @@ impl Device { .load(Ordering::Acquire); if let Err(error) = unsafe { let fence = self.fence.read(); - self.raw().wait(&fence, current_index, CLEANUP_WAIT_MS) + self.raw() + .wait(fence.as_ref(), current_index, CLEANUP_WAIT_MS) } { log::error!("failed to wait for the device: {error}"); } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 1357a2e423..02049a4c31 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -244,7 +244,8 @@ impl Hub { if let Some(device) = present.device.downcast_ref::() { let suf = A::surface_as_hal(surface); unsafe { - suf.unwrap().unconfigure(device.raw()); + suf.unwrap() + .unconfigure(device.raw().as_any().downcast_ref().unwrap()); } } } diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 9ddbaae2d5..4c1b9960c1 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -267,7 +267,7 @@ impl Adapter { api_log!("Adapter::create_device"); if let Ok(device) = Device::new( - hal_device.device, + Box::new(hal_device.device), &hal_device.queue, self, desc, @@ -275,7 +275,7 @@ impl Adapter { instance_flags, ) { let device = Arc::new(device); - let queue = Arc::new(Queue::new(device.clone(), hal_device.queue)); + let queue = Arc::new(Queue::new(device.clone(), Box::new(hal_device.queue))); device.set_queue(&queue); return Ok((device, queue)); } @@ -662,7 +662,7 @@ impl Global { if let Some(surface) = surface { if let Some(device) = present.device.downcast_ref::() { use hal::Surface; - unsafe { surface.unconfigure(device.raw()) }; + unsafe { surface.unconfigure(device.raw().as_any().downcast_ref().unwrap()) }; } } } diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 59226051e5..80929c3b87 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -47,7 +47,7 @@ pub struct ShaderModuleDescriptor<'a> { #[derive(Debug)] pub struct ShaderModule { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, pub(crate) interface: Option, /// The `label` from the descriptor used to create the resource. @@ -60,7 +60,6 @@ impl Drop for ShaderModule { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_shader_module(raw); } } @@ -72,8 +71,8 @@ crate::impl_parent_device!(ShaderModule); crate::impl_storage_item!(ShaderModule); impl ShaderModule { - pub(crate) fn raw(&self) -> &A::ShaderModule { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule { + self.raw.as_ref() } pub(crate) fn finalize_entry_point_name( @@ -242,7 +241,7 @@ pub enum CreateComputePipelineError { #[derive(Debug)] pub struct ComputePipeline { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) layout: Arc>, pub(crate) device: Arc>, pub(crate) _shader_module: Arc>, @@ -258,7 +257,6 @@ impl Drop for ComputePipeline { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_compute_pipeline(raw); } } @@ -271,8 +269,8 @@ crate::impl_storage_item!(ComputePipeline); crate::impl_trackable!(ComputePipeline); impl ComputePipeline { - pub(crate) fn raw(&self) -> &A::ComputePipeline { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline { + self.raw.as_ref() } } @@ -301,7 +299,7 @@ impl From for CreatePipelineCacheError { #[derive(Debug)] pub struct PipelineCache { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -313,7 +311,6 @@ impl Drop for PipelineCache { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_pipeline_cache(raw); } } @@ -325,8 +322,8 @@ crate::impl_parent_device!(PipelineCache); crate::impl_storage_item!(PipelineCache); impl PipelineCache { - pub(crate) fn raw(&self) -> &A::PipelineCache { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache { + self.raw.as_ref() } } @@ -592,7 +589,7 @@ impl Default for VertexStep { #[derive(Debug)] pub struct RenderPipeline { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, pub(crate) layout: Arc>, pub(crate) _shader_modules: @@ -613,7 +610,6 @@ impl Drop for RenderPipeline { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_render_pipeline(raw); } } @@ -626,7 +622,7 @@ crate::impl_storage_item!(RenderPipeline); crate::impl_trackable!(RenderPipeline); impl RenderPipeline { - pub(crate) fn raw(&self) -> &A::RenderPipeline { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline { + self.raw.as_ref() } } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 3521f04388..d0f09a97f7 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -9,7 +9,7 @@ When this texture is presented, we remove it from the device tracker as well as extract it from the hub. !*/ -use std::{borrow::Borrow, mem::ManuallyDrop, sync::Arc}; +use std::{mem::ManuallyDrop, sync::Arc}; #[cfg(feature = "trace")] use crate::device::trace::Action; @@ -23,7 +23,6 @@ use crate::{ resource::{self, Trackable}, }; -use hal::{Queue as _, Surface as _}; use thiserror::Error; use wgt::SurfaceStatus as Status; @@ -156,9 +155,10 @@ impl Global { let suf = A::surface_as_hal(surface.as_ref()); let (texture_id, status) = match unsafe { + use hal::DynSurface; suf.unwrap().acquire_texture( Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), - &fence, + fence.as_ref(), ) } { Ok(Some(ast)) => { @@ -195,11 +195,9 @@ impl Global { range: wgt::ImageSubresourceRange::default(), }; let clear_view = unsafe { - hal::Device::create_texture_view( - device.raw(), - ast.texture.borrow(), - &clear_view_desc, - ) + device + .raw() + .create_texture_view(ast.texture.as_ref().borrow(), &clear_view_desc) } .map_err(DeviceError::from)?; @@ -386,6 +384,7 @@ impl Global { match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { if surface_id == parent_id { + use hal::DynSurface; unsafe { suf.unwrap().discard_texture(raw) }; } else { log::warn!("Surface texture is outdated"); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index f6742ba825..6a3c02ece4 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -17,14 +17,12 @@ use crate::{ Label, LabelHelpers, }; -use hal::CommandEncoder; use smallvec::SmallVec; use thiserror::Error; use std::{ borrow::{Borrow, Cow}, fmt::Debug, - iter, mem::{self, ManuallyDrop}, ops::Range, ptr::NonNull, @@ -426,7 +424,7 @@ pub type BufferDescriptor<'a> = wgt::BufferDescriptor>; #[derive(Debug)] pub struct Buffer { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, pub(crate) device: Arc>, pub(crate) usage: wgt::BufferUsages, pub(crate) size: wgt::BufferAddress, @@ -443,7 +441,6 @@ impl Drop for Buffer { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_buffer(raw); } } @@ -451,16 +448,17 @@ impl Drop for Buffer { } impl Buffer { - pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a A::Buffer> { - self.raw.get(guard) + pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a dyn hal::DynBuffer> { + self.raw.get(guard).map(|b| b.as_ref()) } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::Buffer, DestroyedResourceError> { + ) -> Result<&dyn hal::DynBuffer, DestroyedResourceError> { self.raw .get(guard) + .map(|raw| raw.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } @@ -611,8 +609,6 @@ impl Buffer { self: &Arc, #[cfg(feature = "trace")] buffer_id: BufferId, ) -> Result, BufferAccessError> { - use hal::Device; - let device = &self.device; let snatch_guard = device.snatchable_lock.read(); let raw_buf = self.try_raw(&snatch_guard)?; @@ -642,20 +638,18 @@ impl Buffer { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }; - let transition_dst = hal::BufferBarrier { + let transition_dst = hal::BufferBarrier:: { buffer: raw_buf, usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, }; let encoder = pending_writes.activate(); unsafe { - encoder.transition_buffers( - iter::once(transition_src).chain(iter::once(transition_dst)), - ); + encoder.transition_buffers(&[transition_src, transition_dst]); if self.size > 0 { encoder.copy_buffer_to_buffer( staging_buffer.raw(), raw_buf, - region.into_iter(), + region.as_slice(), ); } } @@ -689,7 +683,7 @@ impl Buffer { }); } if !mapping.is_coherent { - unsafe { device.raw().flush_mapped_ranges(raw_buf, iter::once(range)) }; + unsafe { device.raw().flush_mapped_ranges(raw_buf, &[range]) }; } } unsafe { device.raw().unmap_buffer(raw_buf) }; @@ -766,7 +760,7 @@ crate::impl_trackable!(Buffer); /// A buffer that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] pub struct DestroyedBuffer { - raw: ManuallyDrop, + raw: ManuallyDrop>, device: Arc>, label: String, bind_groups: Vec>>, @@ -790,8 +784,7 @@ impl Drop for DestroyedBuffer { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; - self.device.raw().destroy_buffer(raw); + hal::DynDevice::destroy_buffer(self.device.raw(), raw); } } } @@ -822,7 +815,7 @@ unsafe impl Sync for StagingBuffer {} /// [`Device::pending_writes`]: crate::device::Device #[derive(Debug)] pub struct StagingBuffer { - raw: A::Buffer, + raw: Box, device: Arc>, pub(crate) size: wgt::BufferSize, is_coherent: bool, @@ -831,7 +824,6 @@ pub struct StagingBuffer { impl StagingBuffer { pub(crate) fn new(device: &Arc>, size: wgt::BufferSize) -> Result { - use hal::Device; profiling::scope!("StagingBuffer::new"); let stage_desc = hal::BufferDescriptor { label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags), @@ -841,7 +833,7 @@ impl StagingBuffer { }; let raw = unsafe { device.raw().create_buffer(&stage_desc)? }; - let mapping = unsafe { device.raw().map_buffer(&raw, 0..size.get()) }?; + let mapping = unsafe { device.raw().map_buffer(raw.as_ref(), 0..size.get()) }?; let staging_buffer = StagingBuffer { raw, @@ -900,12 +892,14 @@ impl StagingBuffer { } pub(crate) fn flush(self) -> FlushedStagingBuffer { - use hal::Device; let device = self.device.raw(); if !self.is_coherent { - unsafe { device.flush_mapped_ranges(&self.raw, iter::once(0..self.size.get())) }; + #[allow(clippy::single_range_in_vec_init)] + unsafe { + device.flush_mapped_ranges(self.raw.as_ref(), &[0..self.size.get()]) + }; } - unsafe { device.unmap_buffer(&self.raw) }; + unsafe { device.unmap_buffer(self.raw.as_ref()) }; let StagingBuffer { raw, device, size, .. @@ -924,20 +918,19 @@ crate::impl_storage_item!(StagingBuffer); #[derive(Debug)] pub struct FlushedStagingBuffer { - raw: ManuallyDrop, + raw: ManuallyDrop>, device: Arc>, pub(crate) size: wgt::BufferSize, } impl FlushedStagingBuffer { - pub(crate) fn raw(&self) -> &A::Buffer { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynBuffer { + self.raw.as_ref() } } impl Drop for FlushedStagingBuffer { fn drop(&mut self) { - use hal::Device; resource_log!("Destroy raw StagingBuffer"); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; @@ -948,35 +941,35 @@ impl Drop for FlushedStagingBuffer { pub type TextureDescriptor<'a> = wgt::TextureDescriptor, Vec>; #[derive(Debug)] -pub(crate) enum TextureInner { +pub(crate) enum TextureInner { Native { - raw: A::Texture, + raw: Box, }, Surface { - raw: A::SurfaceTexture, + raw: Box, parent_id: SurfaceId, }, } -impl TextureInner { - pub(crate) fn raw(&self) -> &A::Texture { +impl TextureInner { + pub(crate) fn raw(&self) -> &dyn hal::DynTexture { match self { - Self::Native { raw } => raw, - Self::Surface { raw, .. } => raw.borrow(), + Self::Native { raw } => raw.as_ref(), + Self::Surface { raw, .. } => raw.as_ref().borrow(), } } } #[derive(Debug)] -pub enum TextureClearMode { +pub enum TextureClearMode { BufferCopy, // View for clear via RenderPass for every subsurface (mip/layer/slice) RenderPass { - clear_views: SmallVec<[ManuallyDrop; 1]>, + clear_views: SmallVec<[ManuallyDrop>; 1]>, is_color: bool, }, Surface { - clear_view: ManuallyDrop, + clear_view: ManuallyDrop>, }, // Texture can't be cleared, attempting to do so will cause panic. // (either because it is impossible for the type of texture or it is being destroyed) @@ -985,7 +978,7 @@ pub enum TextureClearMode { #[derive(Debug)] pub struct Texture { - pub(crate) inner: Snatchable>, + pub(crate) inner: Snatchable, pub(crate) device: Arc>, pub(crate) desc: wgt::TextureDescriptor<(), Vec>, pub(crate) hal_usage: hal::TextureUses, @@ -995,7 +988,7 @@ pub struct Texture { /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, - pub(crate) clear_mode: TextureClearMode, + pub(crate) clear_mode: TextureClearMode, pub(crate) views: Mutex>>>, pub(crate) bind_groups: Mutex>>>, } @@ -1003,11 +996,11 @@ pub struct Texture { impl Texture { pub(crate) fn new( device: &Arc>, - inner: TextureInner, + inner: TextureInner, hal_usage: hal::TextureUses, desc: &TextureDescriptor, format_features: wgt::TextureFormatFeatures, - clear_mode: TextureClearMode, + clear_mode: TextureClearMode, init: bool, ) -> Self { Texture { @@ -1055,7 +1048,6 @@ impl Texture { impl Drop for Texture { fn drop(&mut self) { - use hal::Device; match self.clear_mode { TextureClearMode::Surface { ref mut clear_view, .. @@ -1094,20 +1086,23 @@ impl Texture { pub(crate) fn try_inner<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&'a TextureInner, DestroyedResourceError> { + ) -> Result<&'a TextureInner, DestroyedResourceError> { self.inner .get(guard) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } - pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::Texture> { + pub(crate) fn raw<'a>( + &'a self, + snatch_guard: &'a SnatchGuard, + ) -> Option<&'a dyn hal::DynTexture> { Some(self.inner.get(snatch_guard)?.raw()) } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&'a A::Texture, DestroyedResourceError> { + ) -> Result<&'a dyn hal::DynTexture, DestroyedResourceError> { self.inner .get(guard) .map(|t| t.raw()) @@ -1115,11 +1110,11 @@ impl Texture { } pub(crate) fn get_clear_view<'a>( - clear_mode: &'a TextureClearMode, + clear_mode: &'a TextureClearMode, desc: &'a wgt::TextureDescriptor<(), Vec>, mip_level: u32, depth_or_layer: u32, - ) -> &'a A::TextureView { + ) -> &'a dyn hal::DynTextureView { match *clear_mode { TextureClearMode::BufferCopy => { panic!("Given texture is cleared with buffer copies, not render passes") @@ -1127,7 +1122,7 @@ impl Texture { TextureClearMode::None => { panic!("Given texture can't be cleared") } - TextureClearMode::Surface { ref clear_view, .. } => clear_view, + TextureClearMode::Surface { ref clear_view, .. } => clear_view.as_ref(), TextureClearMode::RenderPass { ref clear_views, .. } => { @@ -1138,7 +1133,7 @@ impl Texture { } else { mip_level * desc.size.depth_or_array_layers } + depth_or_layer; - &clear_views[index as usize] + clear_views[index as usize].as_ref() } } } @@ -1207,7 +1202,9 @@ impl Global { if let Ok(buffer) = hub.buffers.get(id) { let snatch_guard = buffer.device.snatchable_lock.read(); - let hal_buffer = buffer.raw(&snatch_guard); + let hal_buffer = buffer + .raw(&snatch_guard) + .and_then(|b| b.as_any().downcast_ref()); hal_buffer_callback(hal_buffer) } else { hal_buffer_callback(None) @@ -1229,6 +1226,9 @@ impl Global { if let Ok(texture) = hub.textures.get(id) { let snatch_guard = texture.device.snatchable_lock.read(); let hal_texture = texture.raw(&snatch_guard); + let hal_texture = hal_texture + .as_ref() + .and_then(|it| it.as_any().downcast_ref()); hal_texture_callback(hal_texture) } else { hal_texture_callback(None) @@ -1250,6 +1250,9 @@ impl Global { if let Ok(texture_view) = hub.texture_views.get(id) { let snatch_guard = texture_view.device.snatchable_lock.read(); let hal_texture_view = texture_view.raw(&snatch_guard); + let hal_texture_view = hal_texture_view + .as_ref() + .and_then(|it| it.as_any().downcast_ref()); hal_texture_view_callback(hal_texture_view) } else { hal_texture_view_callback(None) @@ -1285,7 +1288,10 @@ impl Global { let hub = A::hub(self); let device = hub.devices.get(id).ok(); - let hal_device = device.as_ref().map(|device| device.raw()); + let hal_device = device + .as_ref() + .map(|device| device.raw()) + .and_then(|device| device.as_any().downcast_ref()); hal_device_callback(hal_device) } @@ -1304,7 +1310,7 @@ impl Global { if let Ok(device) = hub.devices.get(id) { let fence = device.fence.read(); - hal_fence_callback(Some(&fence)) + hal_fence_callback(fence.as_any().downcast_ref()) } else { hal_fence_callback(None) } @@ -1346,7 +1352,11 @@ impl Global { if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) { let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); - let cmd_buf_raw = cmd_buf_data.encoder.open().ok(); + let cmd_buf_raw = cmd_buf_data + .encoder + .open() + .ok() + .and_then(|encoder| encoder.as_any_mut().downcast_mut()); hal_command_encoder_callback(cmd_buf_raw) } else { hal_command_encoder_callback(None) @@ -1357,7 +1367,7 @@ impl Global { /// A texture that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] pub struct DestroyedTexture { - raw: ManuallyDrop, + raw: ManuallyDrop>, views: Vec>>, bind_groups: Vec>>, device: Arc>, @@ -1387,7 +1397,6 @@ impl Drop for DestroyedTexture { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_texture(raw); } } @@ -1553,7 +1562,7 @@ pub enum TextureViewNotRenderableReason { #[derive(Debug)] pub struct TextureView { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, // if it's a surface texture - it's none pub(crate) parent: Arc>, pub(crate) device: Arc>, @@ -1573,7 +1582,6 @@ impl Drop for TextureView { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_texture_view(raw); } } @@ -1581,16 +1589,20 @@ impl Drop for TextureView { } impl TextureView { - pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::TextureView> { - self.raw.get(snatch_guard) + pub(crate) fn raw<'a>( + &'a self, + snatch_guard: &'a SnatchGuard, + ) -> Option<&'a dyn hal::DynTextureView> { + self.raw.get(snatch_guard).map(|it| it.as_ref()) } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::TextureView, DestroyedResourceError> { + ) -> Result<&'a dyn hal::DynTextureView, DestroyedResourceError> { self.raw .get(guard) + .map(|it| it.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } } @@ -1687,7 +1699,7 @@ pub struct SamplerDescriptor<'a> { #[derive(Debug)] pub struct Sampler { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1704,15 +1716,14 @@ impl Drop for Sampler { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_sampler(raw); } } } impl Sampler { - pub(crate) fn raw(&self) -> &A::Sampler { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynSampler { + self.raw.as_ref() } } @@ -1783,7 +1794,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor>; #[derive(Debug)] pub struct QuerySet { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1797,7 +1808,6 @@ impl Drop for QuerySet { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_query_set(raw); } } @@ -1810,8 +1820,8 @@ crate::impl_storage_item!(QuerySet); crate::impl_trackable!(QuerySet); impl QuerySet { - pub(crate) fn raw(&self) -> &A::QuerySet { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet { + self.raw.as_ref() } } diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 0f2bc8cef9..ea670de35a 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -284,7 +284,7 @@ impl BufferTracker { pub fn drain_transitions<'a, 'b: 'a>( &'b mut self, snatch_guard: &'a SnatchGuard<'a>, - ) -> impl Iterator> { + ) -> impl Iterator> { let buffer_barriers = self.temp.drain(..).map(|pending| { let buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) }; pending.into_hal(buf, snatch_guard) @@ -557,7 +557,7 @@ impl DeviceBufferTracker { &'a mut self, tracker: &'a BufferTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 4fccb24abe..a75092d8be 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -261,7 +261,7 @@ impl PendingTransition { self, buf: &'a resource::Buffer, snatch_guard: &'a SnatchGuard<'a>, - ) -> hal::BufferBarrier<'a, A::Buffer> { + ) -> hal::BufferBarrier<'a, dyn hal::DynBuffer> { let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed"); hal::BufferBarrier { buffer, @@ -272,10 +272,10 @@ impl PendingTransition { impl PendingTransition { /// Produce the hal barrier corresponding to the transition. - pub fn into_hal<'a, T: hal::DynTexture + ?Sized>( + pub fn into_hal( self, - texture: &'a T, - ) -> hal::TextureBarrier<'a, T> { + texture: &dyn hal::DynTexture, + ) -> hal::TextureBarrier<'_, dyn hal::DynTexture> { // These showing up in a barrier is always a bug strict_assert_ne!(self.usage.start, hal::TextureUses::UNKNOWN); strict_assert_ne!(self.usage.end, hal::TextureUses::UNKNOWN); diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index f454c3e225..9b11527645 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -438,7 +438,7 @@ impl TextureTracker { pub fn drain_transitions<'a>( &'a mut self, snatch_guard: &'a SnatchGuard<'a>, - ) -> (PendingTransitionList, Vec>>) { + ) -> (PendingTransitionList, Vec>) { let mut textures = Vec::new(); let transitions = self .temp @@ -754,7 +754,7 @@ impl DeviceTextureTracker { &'a mut self, tracker: &'a TextureTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); @@ -798,7 +798,7 @@ impl DeviceTextureTracker { &'a mut self, scope: &'a TextureUsageScope, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in scope.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 06632d68dd..b787130ba4 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -143,7 +143,7 @@ impl ContextWgpuCore { let descriptor = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec()); let (id, error) = unsafe { self.0 - .create_texture_from_hal::(hal_texture, device.id, &descriptor, None) + .create_texture_from_hal::(Box::new(hal_texture), device.id, &descriptor, None) }; if let Some(cause) = error { self.handle_error( From 4a688cbb8c140461e40320ecb0617c6063a69ed9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 4 Aug 2024 21:48:07 +0200 Subject: [PATCH 45/53] Core's Surface, Instance and Adapter use now dynamic hal types --- wgpu-core/src/device/global.rs | 12 +- wgpu-core/src/global.rs | 96 ++++---- wgpu-core/src/hal_api.rs | 77 +----- wgpu-core/src/hub.rs | 7 +- wgpu-core/src/instance.rs | 392 ++++++++++++++----------------- wgpu-core/src/present.rs | 14 +- wgpu-core/src/resource.rs | 8 +- wgpu-hal/src/dynamic/adapter.rs | 13 +- wgpu-hal/src/dynamic/instance.rs | 13 +- wgpu/src/backend/wgpu_core.rs | 9 +- 10 files changed, 280 insertions(+), 361 deletions(-) diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index cb9f62ea03..b50dcb9593 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -56,7 +56,7 @@ impl Global { ) -> Result { profiling::scope!("Surface::get_capabilities"); self.fetch_adapter_and_surface::(surface_id, adapter_id, |adapter, surface| { - let mut hal_caps = surface.get_capabilities(adapter)?; + let mut hal_caps = surface.get_capabilities::(A::VARIANT, adapter)?; hal_caps.formats.sort_by_key(|f| !f.is_srgb()); @@ -1765,7 +1765,6 @@ impl Global { device_id: DeviceId, config: &wgt::SurfaceConfiguration>, ) -> Option { - use hal::Surface as _; use present::ConfigureSurfaceError as E; profiling::scope!("surface_configure"); @@ -1909,7 +1908,7 @@ impl Global { Err(_) => break 'error E::InvalidSurface, }; - let caps = match surface.get_capabilities(&device.adapter) { + let caps = match surface.get_capabilities::(A::VARIANT, &device.adapter) { Ok(caps) => caps, Err(_) => break 'error E::UnsupportedQueueFamily, }; @@ -1990,11 +1989,8 @@ impl Global { // // https://github.com/gfx-rs/wgpu/issues/4105 - match unsafe { - A::surface_as_hal(surface) - .unwrap() - .configure(device.raw().as_any().downcast_ref().unwrap(), &hal_config) - } { + let surface_raw = surface.raw(A::VARIANT).unwrap(); + match unsafe { surface_raw.configure(device.raw(), &hal_config) } { Ok(()) => (), Err(error) => { break 'error match error { diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index 54dcc8111c..e4708fd4dc 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use wgt::Backend; use crate::{ @@ -11,14 +13,7 @@ use crate::{ #[derive(Debug, PartialEq, Eq)] pub struct GlobalReport { pub surfaces: RegistryReport, - #[cfg(vulkan)] - pub vulkan: Option, - #[cfg(metal)] - pub metal: Option, - #[cfg(dx12)] - pub dx12: Option, - #[cfg(gles)] - pub gl: Option, + pub report_per_backend: HashMap, } impl GlobalReport { @@ -26,17 +21,7 @@ impl GlobalReport { &self.surfaces } pub fn hub_report(&self, backend: Backend) -> &HubReport { - match backend { - #[cfg(vulkan)] - Backend::Vulkan => self.vulkan.as_ref().unwrap(), - #[cfg(metal)] - Backend::Metal => self.metal.as_ref().unwrap(), - #[cfg(dx12)] - Backend::Dx12 => self.dx12.as_ref().unwrap(), - #[cfg(gles)] - Backend::Gl => self.gl.as_ref().unwrap(), - _ => panic!("HubReport is not supported on this backend"), - } + self.report_per_backend.get(&backend).unwrap() } } @@ -61,8 +46,14 @@ impl Global { /// Refer to the creation of wgpu-hal Instance for every backend. pub unsafe fn from_hal_instance(name: &str, hal_instance: A::Instance) -> Self { profiling::scope!("Global::new"); + + let dyn_instance: Box = Box::new(hal_instance); Self { - instance: A::create_instance_from_hal(name, hal_instance), + instance: Instance { + name: name.to_owned(), + instance_per_backend: std::iter::once((A::VARIANT, dyn_instance)).collect(), + ..Default::default() + }, surfaces: Registry::without_backend(), hubs: Hubs::new(), } @@ -72,7 +63,13 @@ impl Global { /// /// - The raw instance handle returned must not be manually destroyed. pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { - A::instance_as_hal(&self.instance) + self.instance.raw(A::VARIANT).map(|instance| { + instance + .as_any() + .downcast_ref() + // This should be impossible. It would mean that backend instance and enum type are mismatching. + .expect("Stored instance is not of the correct type") + }) } /// # Safety @@ -88,32 +85,41 @@ impl Global { } pub fn generate_report(&self) -> GlobalReport { + let mut report_per_backend = HashMap::default(); + let instance_per_backend = &self.instance.instance_per_backend; + + #[cfg(vulkan)] + if instance_per_backend + .iter() + .any(|(backend, _)| backend == &Backend::Vulkan) + { + report_per_backend.insert(Backend::Vulkan, self.hubs.vulkan.generate_report()); + }; + #[cfg(metal)] + if instance_per_backend + .iter() + .any(|(backend, _)| backend == &Backend::Metal) + { + report_per_backend.insert(Backend::Metal, self.hubs.metal.generate_report()); + }; + #[cfg(dx12)] + if instance_per_backend + .iter() + .any(|(backend, _)| backend == &Backend::Dx12) + { + report_per_backend.insert(Backend::Dx12, self.hubs.dx12.generate_report()); + }; + #[cfg(gles)] + if instance_per_backend + .iter() + .any(|(backend, _)| backend == &Backend::Gl) + { + report_per_backend.insert(Backend::Gl, self.hubs.gl.generate_report()); + }; + GlobalReport { surfaces: self.surfaces.generate_report(), - #[cfg(vulkan)] - vulkan: if self.instance.vulkan.is_some() { - Some(self.hubs.vulkan.generate_report()) - } else { - None - }, - #[cfg(metal)] - metal: if self.instance.metal.is_some() { - Some(self.hubs.metal.generate_report()) - } else { - None - }, - #[cfg(dx12)] - dx12: if self.instance.dx12.is_some() { - Some(self.hubs.dx12.generate_report()) - } else { - None - }, - #[cfg(gles)] - gl: if self.instance.gl.is_some() { - Some(self.hubs.gl.generate_report()) - } else { - None - }, + report_per_backend, } } } diff --git a/wgpu-core/src/hal_api.rs b/wgpu-core/src/hal_api.rs index f1a40b1cff..ebd09ffc73 100644 --- a/wgpu-core/src/hal_api.rs +++ b/wgpu-core/src/hal_api.rs @@ -1,116 +1,53 @@ use wgt::{Backend, WasmNotSendSync}; -use crate::{ - global::Global, - hub::Hub, - instance::{Instance, Surface}, -}; +use crate::{global::Global, hub::Hub}; pub trait HalApi: hal::Api + 'static + WasmNotSendSync { const VARIANT: Backend; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance; - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance>; + fn hub(global: &Global) -> &Hub; - fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface>; } impl HalApi for hal::api::Empty { const VARIANT: Backend = Backend::Empty; - fn create_instance_from_hal(_: &str, _: Self::Instance) -> Instance { - unimplemented!("called empty api") - } - fn instance_as_hal(_: &Instance) -> Option<&Self::Instance> { - unimplemented!("called empty api") - } + fn hub(_: &Global) -> &Hub { unimplemented!("called empty api") } - fn surface_as_hal(_: &Surface) -> Option<&Self::Surface> { - unimplemented!("called empty api") - } } #[cfg(vulkan)] impl HalApi for hal::api::Vulkan { const VARIANT: Backend = Backend::Vulkan; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { - Instance { - name: name.to_owned(), - vulkan: Some(hal_instance), - ..Default::default() - } - } - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> { - instance.vulkan.as_ref() - } + fn hub(global: &Global) -> &Hub { &global.hubs.vulkan } - fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> { - surface.vulkan.as_ref() - } } #[cfg(metal)] impl HalApi for hal::api::Metal { const VARIANT: Backend = Backend::Metal; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { - Instance { - name: name.to_owned(), - metal: Some(hal_instance), - ..Default::default() - } - } - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> { - instance.metal.as_ref() - } + fn hub(global: &Global) -> &Hub { &global.hubs.metal } - fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> { - surface.metal.as_ref() - } } #[cfg(dx12)] impl HalApi for hal::api::Dx12 { const VARIANT: Backend = Backend::Dx12; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { - Instance { - name: name.to_owned(), - dx12: Some(hal_instance), - ..Default::default() - } - } - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> { - instance.dx12.as_ref() - } + fn hub(global: &Global) -> &Hub { &global.hubs.dx12 } - fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> { - surface.dx12.as_ref() - } } #[cfg(gles)] impl HalApi for hal::api::Gles { const VARIANT: Backend = Backend::Gl; - fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance { - #[allow(clippy::needless_update)] - Instance { - name: name.to_owned(), - gl: Some(hal_instance), - ..Default::default() - } - } - fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> { - instance.gl.as_ref() - } + fn hub(global: &Global) -> &Hub { &global.hubs.gl } - fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> { - surface.gl.as_ref() - } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 02049a4c31..3dfbe57adc 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -215,8 +215,6 @@ impl Hub { } pub(crate) fn clear(&self, surface_guard: &Storage) { - use hal::Surface; - let mut devices = self.devices.write(); for element in devices.map.iter() { if let Element::Occupied(ref device, _) = *element { @@ -242,10 +240,9 @@ impl Hub { if let Element::Occupied(ref surface, _epoch) = *element { if let Some(ref mut present) = surface.presentation.lock().take() { if let Some(device) = present.device.downcast_ref::() { - let suf = A::surface_as_hal(surface); + let suf = surface.raw(A::VARIANT); unsafe { - suf.unwrap() - .unconfigure(device.raw().as_any().downcast_ref().unwrap()); + suf.unwrap().unconfigure(device.raw()); } } } diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 4c1b9960c1..75f8bb4d45 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -15,12 +15,9 @@ use crate::{ use wgt::{Backend, Backends, PowerPreference}; -use hal::{Adapter as _, Instance as _, OpenDevice}; use thiserror::Error; pub type RequestAdapterOptions = wgt::RequestAdapterOptions; -type HalInstance = ::Instance; -type HalSurface = ::Surface; #[derive(Clone, Debug, Error)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -58,20 +55,20 @@ fn downlevel_default_limits_less_than_default_limits() { pub struct Instance { #[allow(dead_code)] pub name: String, - #[cfg(vulkan)] - pub vulkan: Option>, - #[cfg(metal)] - pub metal: Option>, - #[cfg(dx12)] - pub dx12: Option>, - #[cfg(gles)] - pub gl: Option>, + /// List of instances per backend. + /// + /// The ordering in this list implies prioritization and needs to be preserved. + pub instance_per_backend: Vec<(Backend, Box)>, pub flags: wgt::InstanceFlags, } impl Instance { pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self { - fn init(_: A, instance_desc: &wgt::InstanceDescriptor) -> Option { + fn init( + _: A, + instance_desc: &wgt::InstanceDescriptor, + instance_per_backend: &mut Vec<(Backend, Box)>, + ) { if instance_desc.backends.contains(A::VARIANT.into()) { let hal_desc = hal::InstanceDescriptor { name: "wgpu", @@ -79,10 +76,12 @@ impl Instance { dx12_shader_compiler: instance_desc.dx12_shader_compiler.clone(), gles_minor_version: instance_desc.gles_minor_version, }; - match unsafe { hal::Instance::init(&hal_desc) } { + + use hal::Instance as _; + match unsafe { A::Instance::init(&hal_desc) } { Ok(instance) => { log::debug!("Instance::new: created {:?} backend", A::VARIANT); - Some(instance) + instance_per_backend.push((A::VARIANT, Box::new(instance))); } Err(err) => { log::debug!( @@ -90,41 +89,43 @@ impl Instance { A::VARIANT, err ); - None } } } else { log::trace!("Instance::new: backend {:?} not requested", A::VARIANT); - None } } + let mut instance_per_backend = Vec::new(); + + #[cfg(vulkan)] + init(hal::api::Vulkan, &instance_desc, &mut instance_per_backend); + #[cfg(metal)] + init(hal::api::Metal, &instance_desc, &mut instance_per_backend); + #[cfg(dx12)] + init(hal::api::Dx12, &instance_desc, &mut instance_per_backend); + #[cfg(gles)] + init(hal::api::Gles, &instance_desc, &mut instance_per_backend); + Self { name: name.to_string(), - #[cfg(vulkan)] - vulkan: init(hal::api::Vulkan, &instance_desc), - #[cfg(metal)] - metal: init(hal::api::Metal, &instance_desc), - #[cfg(dx12)] - dx12: init(hal::api::Dx12, &instance_desc), - #[cfg(gles)] - gl: init(hal::api::Gles, &instance_desc), + instance_per_backend, flags: instance_desc.flags, } } + + pub fn raw(&self, backend: Backend) -> Option<&dyn hal::DynInstance> { + self.instance_per_backend + .iter() + .find_map(|(instance_backend, instance)| { + (*instance_backend == backend).then(|| instance.as_ref()) + }) + } } pub struct Surface { pub(crate) presentation: Mutex>, - - #[cfg(vulkan)] - pub vulkan: Option>, - #[cfg(metal)] - pub metal: Option>, - #[cfg(dx12)] - pub dx12: Option>, - #[cfg(gles)] - pub gl: Option>, + pub surface_per_backend: HashMap>, } impl ResourceType for Surface { @@ -137,34 +138,41 @@ impl crate::storage::StorageItem for Surface { impl Surface { pub fn get_capabilities( &self, + backend: Backend, adapter: &Adapter, ) -> Result { - self.get_capabilities_with_raw(&adapter.raw) + self.get_capabilities_with_raw(backend, &adapter.raw) } - pub fn get_capabilities_with_raw( + pub fn get_capabilities_with_raw( &self, - adapter: &hal::ExposedAdapter, + backend: Backend, + adapter: &hal::DynExposedAdapter, ) -> Result { - let suf = A::surface_as_hal(self).ok_or(GetSurfaceSupportError::Unsupported)?; + let suf = self + .raw(backend) + .ok_or(GetSurfaceSupportError::Unsupported)?; profiling::scope!("surface_capabilities"); - let caps = unsafe { - adapter - .adapter - .surface_capabilities(suf) - .ok_or(GetSurfaceSupportError::Unsupported)? - }; + let caps = unsafe { adapter.adapter.surface_capabilities(suf) } + .ok_or(GetSurfaceSupportError::Unsupported)?; Ok(caps) } + + pub fn raw(&self, backend: Backend) -> Option<&dyn hal::DynSurface> { + self.surface_per_backend + .get(&backend) + .map(|surface| surface.as_ref()) + } } pub struct Adapter { - pub(crate) raw: hal::ExposedAdapter, + pub(crate) raw: hal::DynExposedAdapter, + _marker: std::marker::PhantomData, } impl Adapter { - fn new(mut raw: hal::ExposedAdapter) -> Self { + fn new(mut raw: hal::DynExposedAdapter) -> Self { // WebGPU requires this offset alignment as lower bound on all adapters. const MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND: u32 = 32; @@ -177,7 +185,10 @@ impl Adapter { .min_storage_buffer_offset_alignment .max(MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND); - Self { raw } + Self { + raw, + _marker: std::marker::PhantomData, + } } pub fn is_surface_supported(&self, surface: &Surface) -> bool { @@ -185,7 +196,7 @@ impl Adapter { // // This could occur if the user is running their app on Wayland but Vulkan does not support // VK_KHR_wayland_surface. - surface.get_capabilities(self).is_ok() + surface.get_capabilities(A::VARIANT, self).is_ok() } pub(crate) fn get_texture_format_features( @@ -259,7 +270,7 @@ impl Adapter { #[allow(clippy::type_complexity)] fn create_device_and_queue_from_hal( self: &Arc, - hal_device: OpenDevice, + hal_device: hal::DynOpenDevice, desc: &DeviceDescriptor, instance_flags: wgt::InstanceFlags, trace_path: Option<&std::path::Path>, @@ -267,15 +278,15 @@ impl Adapter { api_log!("Adapter::create_device"); if let Ok(device) = Device::new( - Box::new(hal_device.device), - &hal_device.queue, + hal_device.device, + hal_device.queue.as_ref(), self, desc, trace_path, instance_flags, ) { let device = Arc::new(device); - let queue = Arc::new(Queue::new(device.clone(), Box::new(hal_device.queue))); + let queue = Arc::new(Queue::new(device.clone(), hal_device.queue)); device.set_queue(&queue); return Ok((device, queue)); } @@ -456,85 +467,42 @@ impl Global { ) -> Result { profiling::scope!("Instance::create_surface"); - fn init( - errors: &mut HashMap, - any_created: &mut bool, - backend: Backend, - inst: &Option, - display_handle: raw_window_handle::RawDisplayHandle, - window_handle: raw_window_handle::RawWindowHandle, - ) -> Option> { - inst.as_ref().and_then(|inst| { - match unsafe { inst.create_surface(display_handle, window_handle) } { - Ok(raw) => { - *any_created = true; - Some(raw) - } - Err(err) => { - log::debug!( - "Instance::create_surface: failed to create surface for {:?}: {:?}", - backend, - err - ); - errors.insert(backend, err); - None - } - } - }) - } - let mut errors = HashMap::default(); - let mut any_created = false; + let mut surface_per_backend = HashMap::default(); - let surface = Surface { - presentation: Mutex::new(rank::SURFACE_PRESENTATION, None), + for (backend, instance) in &self.instance.instance_per_backend { + match unsafe { + instance + .as_ref() + .create_surface(display_handle, window_handle) + } { + Ok(raw) => { + surface_per_backend.insert(*backend, raw); + } + Err(err) => { + log::debug!( + "Instance::create_surface: failed to create surface for {:?}: {:?}", + backend, + err + ); + errors.insert(*backend, err); + } + } + } - #[cfg(vulkan)] - vulkan: init::( - &mut errors, - &mut any_created, - Backend::Vulkan, - &self.instance.vulkan, - display_handle, - window_handle, - ), - #[cfg(metal)] - metal: init::( - &mut errors, - &mut any_created, - Backend::Metal, - &self.instance.metal, - display_handle, - window_handle, - ), - #[cfg(dx12)] - dx12: init::( - &mut errors, - &mut any_created, - Backend::Dx12, - &self.instance.dx12, - display_handle, - window_handle, - ), - #[cfg(gles)] - gl: init::( - &mut errors, - &mut any_created, - Backend::Gl, - &self.instance.gl, - display_handle, - window_handle, - ), - }; + if surface_per_backend.is_empty() { + Err(CreateSurfaceError::FailedToCreateSurfaceForAnyBackend( + errors, + )) + } else { + let surface = Surface { + presentation: Mutex::new(rank::SURFACE_PRESENTATION, None), + surface_per_backend, + }; - if any_created { #[allow(clippy::arc_with_non_send_sync)] let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); Ok(id) - } else { - Err(CreateSurfaceError::FailedToCreateSurfaceForAnyBackend( - errors, - )) } } @@ -549,33 +517,31 @@ impl Global { ) -> Result { profiling::scope!("Instance::create_surface_metal"); + let instance = self + .instance + .raw(Backend::Metal) + .ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Metal))?; + let instance_metal: &hal::metal::Instance = instance.as_any().downcast_ref().unwrap(); + + let layer = layer.cast(); + // SAFETY: We do this cast and deref. (rather than using `metal` to get the + // object we want) to avoid direct coupling on the `metal` crate. + // + // To wit, this pointer… + // + // - …is properly aligned. + // - …is dereferenceable to a `MetalLayerRef` as an invariant of the `metal` + // field. + // - …points to an _initialized_ `MetalLayerRef`. + // - …is only ever aliased via an immutable reference that lives within this + // lexical scope. + let layer = unsafe { &*layer }; + let raw_surface: Box = + Box::new(instance_metal.create_surface_from_layer(layer)); + let surface = Surface { presentation: Mutex::new(rank::SURFACE_PRESENTATION, None), - metal: Some(self.instance.metal.as_ref().map_or( - Err(CreateSurfaceError::BackendNotEnabled(Backend::Metal)), - |inst| { - let layer = layer.cast(); - // SAFETY: We do this cast and deref. (rather than using `metal` to get the - // object we want) to avoid direct coupling on the `metal` crate. - // - // To wit, this pointer… - // - // - …is properly aligned. - // - …is dereferenceable to a `MetalLayerRef` as an invariant of the `metal` - // field. - // - …points to an _initialized_ `MetalLayerRef`. - // - …is only ever aliased via an immutable reference that lives within this - // lexical scope. - let layer = unsafe { &*layer }; - Ok(inst.create_surface_from_layer(layer)) - }, - )?), - #[cfg(dx12)] - dx12: None, - #[cfg(vulkan)] - vulkan: None, - #[cfg(gles)] - gl: None, + surface_per_backend: std::iter::once((Backend::Metal, raw_surface)).collect(), }; let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); @@ -586,22 +552,18 @@ impl Global { fn instance_create_surface_dx12( &self, id_in: Option, - create_surface_func: impl FnOnce(&HalInstance) -> HalSurface, + create_surface_func: impl FnOnce(&hal::dx12::Instance) -> hal::dx12::Surface, ) -> Result { + let instance = self + .instance + .raw(Backend::Dx12) + .ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Dx12))?; + let instance_dx12 = instance.as_any().downcast_ref().unwrap(); + let surface: Box = Box::new(create_surface_func(instance_dx12)); + let surface = Surface { presentation: Mutex::new(rank::SURFACE_PRESENTATION, None), - dx12: Some(create_surface_func( - self.instance - .dx12 - .as_ref() - .ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Dx12))?, - )), - #[cfg(metal)] - metal: None, - #[cfg(vulkan)] - vulkan: None, - #[cfg(gles)] - gl: None, + surface_per_backend: std::iter::once((Backend::Dx12, surface)).collect(), }; let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); @@ -658,11 +620,10 @@ impl Global { api_log!("Surface::drop {id:?}"); - fn unconfigure(surface: &Option>, present: &Presentation) { - if let Some(surface) = surface { + fn unconfigure(surface: &Surface, present: &Presentation) { + if let Some(surface) = surface.raw(A::VARIANT) { if let Some(device) = present.device.downcast_ref::() { - use hal::Surface; - unsafe { surface.unconfigure(device.raw().as_any().downcast_ref().unwrap()) }; + unsafe { surface.unconfigure(device.raw()) }; } } } @@ -672,27 +633,31 @@ impl Global { .expect("Surface cannot be destroyed because is still in use"); if let Some(present) = surface.presentation.lock().take() { + // TODO(#5124): Becomes a loop once we use Arc #[cfg(vulkan)] - unconfigure::(&surface.vulkan, &present); + unconfigure::(&surface, &present); #[cfg(metal)] - unconfigure::(&surface.metal, &present); + unconfigure::(&surface, &present); #[cfg(dx12)] - unconfigure::(&surface.dx12, &present); + unconfigure::(&surface, &present); #[cfg(gles)] - unconfigure::(&surface.gl, &present); + unconfigure::(&surface, &present); } drop(surface) } fn enumerate( &self, - _: A, - instance: &Option, inputs: &AdapterInputs, list: &mut Vec, ) { - let inst = match *instance { - Some(ref inst) => inst, + let inst = match self + .instance + .instance_per_backend + .iter() + .find(|(backend, _)| backend == &A::VARIANT) + { + Some((_, inst)) => inst.as_ref(), None => return, }; let id_backend = match inputs.find(A::VARIANT) { @@ -700,8 +665,8 @@ impl Global { None => return, }; - profiling::scope!("enumerating", &*format!("{:?}", A::VARIANT)); - let hub = HalApi::hub(self); + profiling::scope!("enumerating", &*format!("{:?}", backend)); + let hub: &crate::hub::Hub = HalApi::hub(self); let hal_adapters = unsafe { inst.enumerate_adapters(None) }; for raw in hal_adapters { @@ -719,23 +684,13 @@ impl Global { let mut adapters = Vec::new(); #[cfg(vulkan)] - self.enumerate( - hal::api::Vulkan, - &self.instance.vulkan, - &inputs, - &mut adapters, - ); + self.enumerate::(&inputs, &mut adapters); #[cfg(metal)] - self.enumerate( - hal::api::Metal, - &self.instance.metal, - &inputs, - &mut adapters, - ); + self.enumerate::(&inputs, &mut adapters); #[cfg(dx12)] - self.enumerate(hal::api::Dx12, &self.instance.dx12, &inputs, &mut adapters); + self.enumerate::(&inputs, &mut adapters); #[cfg(gles)] - self.enumerate(hal::api::Gles, &self.instance.gl, &inputs, &mut adapters); + self.enumerate::(&inputs, &mut adapters); adapters } @@ -744,7 +699,7 @@ impl Global { &self, selected: &mut usize, new_id: Option, - mut list: Vec>, + mut list: Vec, ) -> Option { match selected.checked_sub(list.len()) { Some(left) => { @@ -752,7 +707,7 @@ impl Global { None } None => { - let adapter = Adapter::new(list.swap_remove(*selected)); + let adapter = Adapter::::new(list.swap_remove(*selected)); log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info); let id = HalApi::hub(self) .adapters @@ -771,26 +726,27 @@ impl Global { profiling::scope!("Instance::request_adapter"); api_log!("Instance::request_adapter"); - fn gather( - _: A, - instance: Option<&A::Instance>, + fn gather( + backend: Backend, + instance: &Instance, inputs: &AdapterInputs, compatible_surface: Option<&Surface>, force_software: bool, device_types: &mut Vec, - ) -> (Option>, Vec>) { - let id = inputs.find(A::VARIANT); - match (id, instance) { + ) -> (Option>, Vec) { + let id = inputs.find(backend); + match (id, instance.raw(backend)) { (Some(id), Some(inst)) => { let compatible_hal_surface = - compatible_surface.and_then(|surface| A::surface_as_hal(surface)); + compatible_surface.and_then(|surface| surface.raw(backend)); let mut adapters = unsafe { inst.enumerate_adapters(compatible_hal_surface) }; if force_software { adapters.retain(|exposed| exposed.info.device_type == wgt::DeviceType::Cpu); } if let Some(surface) = compatible_surface { - adapters - .retain(|exposed| surface.get_capabilities_with_raw(exposed).is_ok()); + adapters.retain(|exposed| { + surface.get_capabilities_with_raw(backend, exposed).is_ok() + }); } device_types.extend(adapters.iter().map(|ad| ad.info.device_type)); (id, adapters) @@ -812,8 +768,8 @@ impl Global { #[cfg(vulkan)] let (id_vulkan, adapters_vk) = gather( - hal::api::Vulkan, - self.instance.vulkan.as_ref(), + Backend::Vulkan, + &self.instance, &inputs, compatible_surface, desc.force_fallback_adapter, @@ -821,8 +777,8 @@ impl Global { ); #[cfg(metal)] let (id_metal, adapters_metal) = gather( - hal::api::Metal, - self.instance.metal.as_ref(), + Backend::Metal, + &self.instance, &inputs, compatible_surface, desc.force_fallback_adapter, @@ -830,8 +786,8 @@ impl Global { ); #[cfg(dx12)] let (id_dx12, adapters_dx12) = gather( - hal::api::Dx12, - self.instance.dx12.as_ref(), + Backend::Dx12, + &self.instance, &inputs, compatible_surface, desc.force_fallback_adapter, @@ -839,8 +795,8 @@ impl Global { ); #[cfg(gles)] let (id_gl, adapters_gl) = gather( - hal::api::Gles, - self.instance.gl.as_ref(), + Backend::Gl, + &self.instance, &inputs, compatible_surface, desc.force_fallback_adapter, @@ -899,19 +855,19 @@ impl Global { let mut selected = preferred_gpu.unwrap_or(0); #[cfg(vulkan)] - if let Some(id) = self.select(&mut selected, id_vulkan, adapters_vk) { + if let Some(id) = self.select::(&mut selected, id_vulkan, adapters_vk) { return Ok(id); } #[cfg(metal)] - if let Some(id) = self.select(&mut selected, id_metal, adapters_metal) { + if let Some(id) = self.select::(&mut selected, id_metal, adapters_metal) { return Ok(id); } #[cfg(dx12)] - if let Some(id) = self.select(&mut selected, id_dx12, adapters_dx12) { + if let Some(id) = self.select::(&mut selected, id_dx12, adapters_dx12) { return Ok(id); } #[cfg(gles)] - if let Some(id) = self.select(&mut selected, id_gl, adapters_gl) { + if let Some(id) = self.select::(&mut selected, id_gl, adapters_gl) { return Ok(id); } let _ = selected; @@ -925,7 +881,7 @@ impl Global { /// `hal_adapter` must be created from this global internal instance handle. pub unsafe fn create_adapter_from_hal( &self, - hal_adapter: hal::ExposedAdapter, + hal_adapter: hal::DynExposedAdapter, input: Option, ) -> AdapterId { profiling::scope!("Instance::create_adapter_from_hal"); @@ -934,13 +890,13 @@ impl Global { let id = match A::VARIANT { #[cfg(vulkan)] - Backend::Vulkan => fid.assign(Arc::new(Adapter::new(hal_adapter))), + Backend::Vulkan => fid.assign(Arc::new(Adapter::::new(hal_adapter))), #[cfg(metal)] - Backend::Metal => fid.assign(Arc::new(Adapter::new(hal_adapter))), + Backend::Metal => fid.assign(Arc::new(Adapter::::new(hal_adapter))), #[cfg(dx12)] - Backend::Dx12 => fid.assign(Arc::new(Adapter::new(hal_adapter))), + Backend::Dx12 => fid.assign(Arc::new(Adapter::::new(hal_adapter))), #[cfg(gles)] - Backend::Gl => fid.assign(Arc::new(Adapter::new(hal_adapter))), + Backend::Gl => fid.assign(Arc::new(Adapter::::new(hal_adapter))), _ => unreachable!(), }; resource_log!("Created Adapter {:?}", id); @@ -1076,7 +1032,7 @@ impl Global { pub unsafe fn create_device_from_hal( &self, adapter_id: AdapterId, - hal_device: OpenDevice, + hal_device: hal::DynOpenDevice, desc: &DeviceDescriptor, trace_path: Option<&std::path::Path>, device_id_in: Option, diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index d0f09a97f7..4ac286b497 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -30,7 +30,7 @@ const FRAME_TIMEOUT_MS: u32 = 1000; #[derive(Debug)] pub(crate) struct Presentation { - pub(crate) device: AnyDevice, + pub(crate) device: AnyDevice, // TODO(#5124): use device: Arc pub(crate) config: wgt::SurfaceConfiguration>, pub(crate) acquired_texture: Option, } @@ -153,10 +153,9 @@ impl Global { let fence = device.fence.read(); - let suf = A::surface_as_hal(surface.as_ref()); + let suf = surface.raw(A::VARIANT).unwrap(); let (texture_id, status) = match unsafe { - use hal::DynSurface; - suf.unwrap().acquire_texture( + suf.acquire_texture( Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), fence.as_ref(), ) @@ -304,7 +303,7 @@ impl Global { .lock() .textures .remove(texture.tracker_index()); - let suf = A::surface_as_hal(&surface); + let suf = surface.raw(A::VARIANT).unwrap(); let exclusive_snatch_guard = device.snatchable_lock.write(); match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { @@ -312,7 +311,7 @@ impl Global { log::error!("Presented frame is from a different surface"); Err(hal::SurfaceError::Lost) } else { - unsafe { queue.raw().present(suf.unwrap(), raw) } + unsafe { queue.raw().present(suf, raw) } } } _ => unreachable!(), @@ -379,12 +378,11 @@ impl Global { .lock() .textures .remove(texture.tracker_index()); - let suf = A::surface_as_hal(&surface); + let suf = surface.raw(A::VARIANT); let exclusive_snatch_guard = device.snatchable_lock.write(); match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { if surface_id == parent_id { - use hal::DynSurface; unsafe { suf.unwrap().discard_texture(raw) }; } else { log::warn!("Surface texture is outdated"); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6a3c02ece4..e6a33fa0fb 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1271,7 +1271,10 @@ impl Global { let hub = A::hub(self); let adapter = hub.adapters.get(id).ok(); - let hal_adapter = adapter.as_ref().map(|adapter| &adapter.raw.adapter); + let hal_adapter = adapter + .as_ref() + .map(|adapter| &adapter.raw.adapter) + .and_then(|adapter| adapter.as_any().downcast_ref()); hal_adapter_callback(hal_adapter) } @@ -1328,7 +1331,8 @@ impl Global { let surface = self.surfaces.get(id).ok(); let hal_surface = surface .as_ref() - .and_then(|surface| A::surface_as_hal(surface)); + .and_then(|surface| surface.raw(A::VARIANT)) + .and_then(|surface| surface.as_any().downcast_ref()); hal_surface_callback(hal_surface) } diff --git a/wgpu-hal/src/dynamic/adapter.rs b/wgpu-hal/src/dynamic/adapter.rs index 7f9b63a838..aebe8ec775 100644 --- a/wgpu-hal/src/dynamic/adapter.rs +++ b/wgpu-hal/src/dynamic/adapter.rs @@ -1,4 +1,6 @@ -use crate::{Adapter, DeviceError, SurfaceCapabilities, TextureFormatCapabilities}; +use crate::{ + Adapter, Api, DeviceError, OpenDevice, SurfaceCapabilities, TextureFormatCapabilities, +}; use super::{DynDevice, DynQueue, DynResource, DynResourceExt, DynSurface}; @@ -7,6 +9,15 @@ pub struct DynOpenDevice { pub queue: Box, } +impl From> for DynOpenDevice { + fn from(open_device: OpenDevice) -> Self { + Self { + device: Box::new(open_device.device), + queue: Box::new(open_device.queue), + } + } +} + pub trait DynAdapter: DynResource { unsafe fn open( &self, diff --git a/wgpu-hal/src/dynamic/instance.rs b/wgpu-hal/src/dynamic/instance.rs index 80d834544d..4e811eb0cd 100644 --- a/wgpu-hal/src/dynamic/instance.rs +++ b/wgpu-hal/src/dynamic/instance.rs @@ -1,7 +1,7 @@ // Box casts are needed, alternative would be a temporaries which are more verbose and not more expressive. #![allow(trivial_casts)] -use crate::{Capabilities, Instance, InstanceError}; +use crate::{Api, Capabilities, ExposedAdapter, Instance, InstanceError}; use super::{DynAdapter, DynResource, DynResourceExt as _, DynSurface}; @@ -12,6 +12,17 @@ pub struct DynExposedAdapter { pub capabilities: Capabilities, } +impl From> for DynExposedAdapter { + fn from(exposed_adapter: ExposedAdapter) -> Self { + Self { + adapter: Box::new(exposed_adapter.adapter), + info: exposed_adapter.info, + features: exposed_adapter.features, + capabilities: exposed_adapter.capabilities, + } + } +} + pub trait DynInstance: DynResource { unsafe fn create_surface( &self, diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index b787130ba4..32ee37183f 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -72,7 +72,10 @@ impl ContextWgpuCore { &self, hal_adapter: hal::ExposedAdapter, ) -> wgc::id::AdapterId { - unsafe { self.0.create_adapter_from_hal(hal_adapter, None) } + unsafe { + self.0 + .create_adapter_from_hal::(hal_adapter.into(), None) + } } pub unsafe fn adapter_as_hal< @@ -109,9 +112,9 @@ impl ContextWgpuCore { log::error!("Feature 'trace' has been removed temporarily, see https://github.com/gfx-rs/wgpu/issues/5974"); } let (device_id, queue_id, error) = unsafe { - self.0.create_device_from_hal( + self.0.create_device_from_hal::( *adapter, - hal_device, + hal_device.into(), &desc.map_label(|l| l.map(Borrowed)), None, None, From e24f48a55c65bfdaba0aba499259cb70bac859a2 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sun, 4 Aug 2024 23:01:46 +0200 Subject: [PATCH 46/53] Core adapter no longer uses any generics --- wgpu-core/src/binding_model.rs | 12 ++++----- wgpu-core/src/command/bundle.rs | 4 +-- wgpu-core/src/command/mod.rs | 4 +-- wgpu-core/src/device/global.rs | 6 ++--- wgpu-core/src/device/queue.rs | 4 +-- wgpu-core/src/device/resource.rs | 8 +++--- wgpu-core/src/hub.rs | 2 +- wgpu-core/src/instance.rs | 45 ++++++++++++++------------------ wgpu-core/src/pipeline.rs | 16 ++++++------ wgpu-core/src/resource.rs | 36 ++++++++++++++++--------- wgpu-core/src/storage.rs | 12 ++++++++- wgpu-hal/src/dynamic/instance.rs | 7 +++++ 12 files changed, 88 insertions(+), 68 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 825a96418c..2b45302513 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -530,10 +530,10 @@ impl Drop for BindGroupLayout { } } -crate::impl_resource_type!(BindGroupLayout); +crate::impl_resource_type_generic!(BindGroupLayout); crate::impl_labeled!(BindGroupLayout); crate::impl_parent_device!(BindGroupLayout); -crate::impl_storage_item!(BindGroupLayout); +crate::impl_storage_item_generic!(BindGroupLayout); impl BindGroupLayout { pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout { @@ -761,10 +761,10 @@ impl PipelineLayout { } } -crate::impl_resource_type!(PipelineLayout); +crate::impl_resource_type_generic!(PipelineLayout); crate::impl_labeled!(PipelineLayout); crate::impl_parent_device!(PipelineLayout); -crate::impl_storage_item!(PipelineLayout); +crate::impl_storage_item_generic!(PipelineLayout); #[repr(C)] #[derive(Clone, Debug, Hash, Eq, PartialEq)] @@ -985,10 +985,10 @@ impl BindGroup { } } -crate::impl_resource_type!(BindGroup); +crate::impl_resource_type_generic!(BindGroup); crate::impl_labeled!(BindGroup); crate::impl_parent_device!(BindGroup); -crate::impl_storage_item!(BindGroup); +crate::impl_storage_item_generic!(BindGroup); crate::impl_trackable!(BindGroup); #[derive(Clone, Debug, Error)] diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 2f040e615b..a8a3528647 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -1146,10 +1146,10 @@ impl RenderBundle { } } -crate::impl_resource_type!(RenderBundle); +crate::impl_resource_type_generic!(RenderBundle); crate::impl_labeled!(RenderBundle); crate::impl_parent_device!(RenderBundle); -crate::impl_storage_item!(RenderBundle); +crate::impl_storage_item_generic!(RenderBundle); crate::impl_trackable!(RenderBundle); /// A render bundle's current index buffer state. diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index d16e7f6d05..df9360e775 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -526,10 +526,10 @@ impl CommandBuffer { } } -crate::impl_resource_type!(CommandBuffer); +crate::impl_resource_type_generic!(CommandBuffer); crate::impl_labeled!(CommandBuffer); crate::impl_parent_device!(CommandBuffer); -crate::impl_storage_item!(CommandBuffer); +crate::impl_storage_item_generic!(CommandBuffer); /// A stream of commands for a render pass or compute pass. /// diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index b50dcb9593..f456a00ca2 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -56,7 +56,7 @@ impl Global { ) -> Result { profiling::scope!("Surface::get_capabilities"); self.fetch_adapter_and_surface::(surface_id, adapter_id, |adapter, surface| { - let mut hal_caps = surface.get_capabilities::(A::VARIANT, adapter)?; + let mut hal_caps = surface.get_capabilities(adapter)?; hal_caps.formats.sort_by_key(|f| !f.is_srgb()); @@ -73,7 +73,7 @@ impl Global { fn fetch_adapter_and_surface< A: HalApi, - F: FnOnce(&Adapter, &Surface) -> Result, + F: FnOnce(&Adapter, &Surface) -> Result, B, >( &self, @@ -1908,7 +1908,7 @@ impl Global { Err(_) => break 'error E::InvalidSurface, }; - let caps = match surface.get_capabilities::(A::VARIANT, &device.adapter) { + let caps = match surface.get_capabilities(&device.adapter) { Ok(caps) => caps, Err(_) => break 'error E::UnsupportedQueueFamily, }; diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index fbcbbdcbed..cca59e0b1a 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -55,7 +55,7 @@ impl Queue { } } -crate::impl_resource_type!(Queue); +crate::impl_resource_type_generic!(Queue); // TODO: https://github.com/gfx-rs/wgpu/issues/4014 impl Labeled for Queue { fn label(&self) -> &str { @@ -63,7 +63,7 @@ impl Labeled for Queue { } } crate::impl_parent_device!(Queue); -crate::impl_storage_item!(Queue); +crate::impl_storage_item_generic!(Queue); impl Drop for Queue { fn drop(&mut self) { diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 7801ccd059..a7ce999407 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -79,7 +79,7 @@ use super::{ /// trackers should be locked only when needed for the shortest time possible pub struct Device { raw: ManuallyDrop>, - pub(crate) adapter: Arc>, + pub(crate) adapter: Arc, pub(crate) queue: OnceCell>>, queue_to_drop: OnceCell>, pub(crate) zero_buffer: ManuallyDrop>, @@ -222,7 +222,7 @@ impl Device { pub(crate) fn new( raw_device: Box, raw_queue: &dyn hal::DynQueue, - adapter: &Arc>, + adapter: &Arc, desc: &DeviceDescriptor, trace_path: Option<&std::path::Path>, instance_flags: wgt::InstanceFlags, @@ -3656,6 +3656,6 @@ impl Device { } } -crate::impl_resource_type!(Device); +crate::impl_resource_type_generic!(Device); crate::impl_labeled!(Device); -crate::impl_storage_item!(Device); +crate::impl_storage_item_generic!(Device); diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 3dfbe57adc..a4d04f3f7c 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -170,7 +170,7 @@ impl HubReport { /// /// [`A::hub(global)`]: HalApi::hub pub struct Hub { - pub(crate) adapters: Registry>, + pub(crate) adapters: Registry, pub(crate) devices: Registry>, pub(crate) queues: Registry>, pub(crate) pipeline_layouts: Registry>, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 75f8bb4d45..9c0a5fd3bb 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -136,21 +136,19 @@ impl crate::storage::StorageItem for Surface { } impl Surface { - pub fn get_capabilities( + pub fn get_capabilities( &self, - backend: Backend, - adapter: &Adapter, + adapter: &Adapter, ) -> Result { - self.get_capabilities_with_raw(backend, &adapter.raw) + self.get_capabilities_with_raw(&adapter.raw) } pub fn get_capabilities_with_raw( &self, - backend: Backend, adapter: &hal::DynExposedAdapter, ) -> Result { let suf = self - .raw(backend) + .raw(adapter.backend()) .ok_or(GetSurfaceSupportError::Unsupported)?; profiling::scope!("surface_capabilities"); let caps = unsafe { adapter.adapter.surface_capabilities(suf) } @@ -166,12 +164,11 @@ impl Surface { } } -pub struct Adapter { +pub struct Adapter { pub(crate) raw: hal::DynExposedAdapter, - _marker: std::marker::PhantomData, } -impl Adapter { +impl Adapter { fn new(mut raw: hal::DynExposedAdapter) -> Self { // WebGPU requires this offset alignment as lower bound on all adapters. const MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND: u32 = 32; @@ -185,10 +182,7 @@ impl Adapter { .min_storage_buffer_offset_alignment .max(MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND); - Self { - raw, - _marker: std::marker::PhantomData, - } + Self { raw } } pub fn is_surface_supported(&self, surface: &Surface) -> bool { @@ -196,7 +190,7 @@ impl Adapter { // // This could occur if the user is running their app on Wayland but Vulkan does not support // VK_KHR_wayland_surface. - surface.get_capabilities(A::VARIANT, self).is_ok() + surface.get_capabilities(self).is_ok() } pub(crate) fn get_texture_format_features( @@ -268,7 +262,7 @@ impl Adapter { } #[allow(clippy::type_complexity)] - fn create_device_and_queue_from_hal( + fn create_device_and_queue_from_hal( self: &Arc, hal_device: hal::DynOpenDevice, desc: &DeviceDescriptor, @@ -294,7 +288,7 @@ impl Adapter { } #[allow(clippy::type_complexity)] - fn create_device_and_queue( + fn create_device_and_queue( self: &Arc, desc: &DeviceDescriptor, instance_flags: wgt::InstanceFlags, @@ -707,9 +701,9 @@ impl Global { None } None => { - let adapter = Adapter::::new(list.swap_remove(*selected)); - log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info); - let id = HalApi::hub(self) + let adapter = Adapter::new(list.swap_remove(*selected)); + log::info!("Adapter {:?}", adapter.raw.info); + let id = A::hub(self) .adapters .prepare(new_id) .assign(Arc::new(adapter)); @@ -744,9 +738,8 @@ impl Global { adapters.retain(|exposed| exposed.info.device_type == wgt::DeviceType::Cpu); } if let Some(surface) = compatible_surface { - adapters.retain(|exposed| { - surface.get_capabilities_with_raw(backend, exposed).is_ok() - }); + adapters + .retain(|exposed| surface.get_capabilities_with_raw(exposed).is_ok()); } device_types.extend(adapters.iter().map(|ad| ad.info.device_type)); (id, adapters) @@ -890,13 +883,13 @@ impl Global { let id = match A::VARIANT { #[cfg(vulkan)] - Backend::Vulkan => fid.assign(Arc::new(Adapter::::new(hal_adapter))), + Backend::Vulkan => fid.assign(Arc::new(Adapter::new(hal_adapter))), #[cfg(metal)] - Backend::Metal => fid.assign(Arc::new(Adapter::::new(hal_adapter))), + Backend::Metal => fid.assign(Arc::new(Adapter::new(hal_adapter))), #[cfg(dx12)] - Backend::Dx12 => fid.assign(Arc::new(Adapter::::new(hal_adapter))), + Backend::Dx12 => fid.assign(Arc::new(Adapter::new(hal_adapter))), #[cfg(gles)] - Backend::Gl => fid.assign(Arc::new(Adapter::::new(hal_adapter))), + Backend::Gl => fid.assign(Arc::new(Adapter::new(hal_adapter))), _ => unreachable!(), }; resource_log!("Created Adapter {:?}", id); diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 80929c3b87..7e58962dbc 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -65,10 +65,10 @@ impl Drop for ShaderModule { } } -crate::impl_resource_type!(ShaderModule); +crate::impl_resource_type_generic!(ShaderModule); crate::impl_labeled!(ShaderModule); crate::impl_parent_device!(ShaderModule); -crate::impl_storage_item!(ShaderModule); +crate::impl_storage_item_generic!(ShaderModule); impl ShaderModule { pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule { @@ -262,10 +262,10 @@ impl Drop for ComputePipeline { } } -crate::impl_resource_type!(ComputePipeline); +crate::impl_resource_type_generic!(ComputePipeline); crate::impl_labeled!(ComputePipeline); crate::impl_parent_device!(ComputePipeline); -crate::impl_storage_item!(ComputePipeline); +crate::impl_storage_item_generic!(ComputePipeline); crate::impl_trackable!(ComputePipeline); impl ComputePipeline { @@ -316,10 +316,10 @@ impl Drop for PipelineCache { } } -crate::impl_resource_type!(PipelineCache); +crate::impl_resource_type_generic!(PipelineCache); crate::impl_labeled!(PipelineCache); crate::impl_parent_device!(PipelineCache); -crate::impl_storage_item!(PipelineCache); +crate::impl_storage_item_generic!(PipelineCache); impl PipelineCache { pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache { @@ -615,10 +615,10 @@ impl Drop for RenderPipeline { } } -crate::impl_resource_type!(RenderPipeline); +crate::impl_resource_type_generic!(RenderPipeline); crate::impl_labeled!(RenderPipeline); crate::impl_parent_device!(RenderPipeline); -crate::impl_storage_item!(RenderPipeline); +crate::impl_storage_item_generic!(RenderPipeline); crate::impl_trackable!(RenderPipeline); impl RenderPipeline { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index e6a33fa0fb..2b06799a24 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -135,8 +135,9 @@ pub(crate) trait ResourceType { const TYPE: &'static str; } +// TODO(#5124): Remove the typed version. #[macro_export] -macro_rules! impl_resource_type { +macro_rules! impl_resource_type_generic { ($ty:ident) => { impl $crate::resource::ResourceType for $ty { const TYPE: &'static str = stringify!($ty); @@ -144,6 +145,15 @@ macro_rules! impl_resource_type { }; } +#[macro_export] +macro_rules! impl_resource_type { + ($ty:ident) => { + impl $crate::resource::ResourceType for $ty { + const TYPE: &'static str = stringify!($ty); + } + }; +} + pub(crate) trait Labeled: ResourceType { /// Returns a string identifying this resource for logging and errors. /// @@ -751,10 +761,10 @@ pub enum CreateBufferError { MissingDownlevelFlags(#[from] MissingDownlevelFlags), } -crate::impl_resource_type!(Buffer); +crate::impl_resource_type_generic!(Buffer); crate::impl_labeled!(Buffer); crate::impl_parent_device!(Buffer); -crate::impl_storage_item!(Buffer); +crate::impl_storage_item_generic!(Buffer); crate::impl_trackable!(Buffer); /// A buffer that has been marked as destroyed and is staged for actual deletion soon. @@ -913,8 +923,8 @@ impl StagingBuffer { } } -crate::impl_resource_type!(StagingBuffer); -crate::impl_storage_item!(StagingBuffer); +crate::impl_resource_type_generic!(StagingBuffer); +crate::impl_storage_item_generic!(StagingBuffer); #[derive(Debug)] pub struct FlushedStagingBuffer { @@ -1498,10 +1508,10 @@ pub enum CreateTextureError { MissingDownlevelFlags(#[from] MissingDownlevelFlags), } -crate::impl_resource_type!(Texture); +crate::impl_resource_type_generic!(Texture); crate::impl_labeled!(Texture); crate::impl_parent_device!(Texture); -crate::impl_storage_item!(Texture); +crate::impl_storage_item_generic!(Texture); crate::impl_trackable!(Texture); impl Borrow for Texture { @@ -1666,10 +1676,10 @@ pub enum CreateTextureViewError { #[non_exhaustive] pub enum TextureViewDestroyError {} -crate::impl_resource_type!(TextureView); +crate::impl_resource_type_generic!(TextureView); crate::impl_labeled!(TextureView); crate::impl_parent_device!(TextureView); -crate::impl_storage_item!(TextureView); +crate::impl_storage_item_generic!(TextureView); crate::impl_trackable!(TextureView); /// Describes a [`Sampler`] @@ -1775,10 +1785,10 @@ pub enum CreateSamplerError { MissingFeatures(#[from] MissingFeatures), } -crate::impl_resource_type!(Sampler); +crate::impl_resource_type_generic!(Sampler); crate::impl_labeled!(Sampler); crate::impl_parent_device!(Sampler); -crate::impl_storage_item!(Sampler); +crate::impl_storage_item_generic!(Sampler); crate::impl_trackable!(Sampler); #[derive(Clone, Debug, Error)] @@ -1817,10 +1827,10 @@ impl Drop for QuerySet { } } -crate::impl_resource_type!(QuerySet); +crate::impl_resource_type_generic!(QuerySet); crate::impl_labeled!(QuerySet); crate::impl_parent_device!(QuerySet); -crate::impl_storage_item!(QuerySet); +crate::impl_storage_item_generic!(QuerySet); crate::impl_trackable!(QuerySet); impl QuerySet { diff --git a/wgpu-core/src/storage.rs b/wgpu-core/src/storage.rs index fda9cbd036..0adcf51abd 100644 --- a/wgpu-core/src/storage.rs +++ b/wgpu-core/src/storage.rs @@ -28,8 +28,9 @@ pub(crate) trait StorageItem: ResourceType { type Marker: Marker; } +// TODO(#5124): Remove the typed version. #[macro_export] -macro_rules! impl_storage_item { +macro_rules! impl_storage_item_generic { ($ty:ident) => { impl $crate::storage::StorageItem for $ty { type Marker = $crate::id::markers::$ty; @@ -37,6 +38,15 @@ macro_rules! impl_storage_item { }; } +#[macro_export] +macro_rules! impl_storage_item { + ($ty:ident) => { + impl $crate::storage::StorageItem for $ty { + type Marker = $crate::id::markers::$ty; + } + }; +} + /// A table of `T` values indexed by the id type `I`. /// /// `Storage` implements [`std::ops::Index`], accepting `Id` values as diff --git a/wgpu-hal/src/dynamic/instance.rs b/wgpu-hal/src/dynamic/instance.rs index 4e811eb0cd..6bac974b17 100644 --- a/wgpu-hal/src/dynamic/instance.rs +++ b/wgpu-hal/src/dynamic/instance.rs @@ -12,6 +12,13 @@ pub struct DynExposedAdapter { pub capabilities: Capabilities, } +impl DynExposedAdapter { + /// Returns the backend this adapter is using. + pub fn backend(&self) -> wgt::Backend { + self.info.backend + } +} + impl From> for DynExposedAdapter { fn from(exposed_adapter: ExposedAdapter) -> Self { Self { From e7deb0c0e12f00720ade22c7716235e136351b4a Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 5 Aug 2024 00:32:03 +0200 Subject: [PATCH 47/53] The second unraveling: hub and all types on it are generic free! gfx_select macros are empty husks now that are waiting to be removed --- deno_webgpu/lib.rs | 20 +- deno_webgpu/surface.rs | 14 +- player/src/lib.rs | 111 ++++--- tests/tests/mem_leaks.rs | 32 +- wgpu-core/src/binding_model.rs | 89 +++-- wgpu-core/src/command/bind.rs | 59 ++-- wgpu-core/src/command/bundle.rs | 149 +++++---- wgpu-core/src/command/clear.rs | 21 +- wgpu-core/src/command/compute.rs | 203 ++++++------ wgpu-core/src/command/compute_command.rs | 23 +- wgpu-core/src/command/dyn_compute_pass.rs | 4 +- wgpu-core/src/command/dyn_render_pass.rs | 4 +- wgpu-core/src/command/memory_init.rs | 52 ++- wgpu-core/src/command/mod.rs | 76 ++--- wgpu-core/src/command/query.rs | 53 ++- wgpu-core/src/command/render.rs | 377 +++++++++++----------- wgpu-core/src/command/render_command.rs | 33 +- wgpu-core/src/command/timestamp_writes.rs | 6 +- wgpu-core/src/command/transfer.rs | 51 ++- wgpu-core/src/device/any_device.rs | 102 ------ wgpu-core/src/device/global.rs | 370 ++++++++++----------- wgpu-core/src/device/life.rs | 40 ++- wgpu-core/src/device/mod.rs | 20 +- wgpu-core/src/device/queue.rs | 122 ++++--- wgpu-core/src/device/resource.rs | 125 +++---- wgpu-core/src/global.rs | 79 +---- wgpu-core/src/hal_api.rs | 24 -- wgpu-core/src/hub.rs | 120 +++---- wgpu-core/src/init_tracker/buffer.rs | 18 +- wgpu-core/src/init_tracker/texture.rs | 12 +- wgpu-core/src/instance.rs | 224 ++++++------- wgpu-core/src/lib.rs | 11 +- wgpu-core/src/pipeline.rs | 88 +++-- wgpu-core/src/present.rs | 47 +-- wgpu-core/src/registry.rs | 22 +- wgpu-core/src/resource.rs | 178 +++++----- wgpu-core/src/storage.rs | 10 - wgpu-core/src/track/buffer.rs | 67 ++-- wgpu-core/src/track/mod.rs | 109 ++++--- wgpu-core/src/track/texture.rs | 83 +++-- wgpu/src/api/surface_texture.rs | 2 - wgpu/src/backend/webgpu.rs | 8 +- wgpu/src/backend/wgpu_core.rs | 31 +- wgpu/src/context.rs | 22 +- 44 files changed, 1465 insertions(+), 1846 deletions(-) delete mode 100644 wgpu-core/src/device/any_device.rs diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index c1822ee2bc..86120be713 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -23,6 +23,7 @@ pub const UNSTABLE_FEATURE_NAME: &str = "webgpu"; #[macro_use] mod macros { + // TODO(#5124): remove this macro. macro_rules! gfx_select { ($id:expr => $p0:ident.$p1:tt.$method:ident $params:tt) => { gfx_select!($id => {$p0.$p1}, $method $params) @@ -33,24 +34,7 @@ mod macros { }; ($id:expr => {$($c:tt)*}, $method:ident $params:tt) => { - match $id.backend() { - #[cfg(any( - all(not(target_arch = "wasm32"), not(target_os = "ios"), not(target_os = "macos")), - feature = "vulkan-portability" - ))] - wgpu_types::Backend::Vulkan => $($c)*.$method:: $params, - #[cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))] - wgpu_types::Backend::Metal => $($c)*.$method:: $params, - #[cfg(all(not(target_arch = "wasm32"), windows))] - wgpu_types::Backend::Dx12 => $($c)*.$method:: $params, - #[cfg(any( - all(unix, not(target_os = "macos"), not(target_os = "ios")), - feature = "angle", - target_arch = "wasm32" - ))] - wgpu_types::Backend::Gl => $($c)*.$method:: $params, - other => panic!("Unexpected backend {:?}", other), - } + $($c)*.$method $params }; } diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index a8b984eefe..9d9ba0d573 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -72,14 +72,10 @@ pub fn op_webgpu_surface_configure( #[serde] pub fn op_webgpu_surface_get_current_texture( state: &mut OpState, - #[smi] device_rid: ResourceId, + #[smi] _device_rid: ResourceId, #[smi] surface_rid: ResourceId, ) -> Result { let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(device_rid)?; - let device = device_resource.1; let surface_resource = state.resource_table.get::(surface_rid)?; let surface = surface_resource.1; @@ -102,18 +98,14 @@ pub fn op_webgpu_surface_get_current_texture( #[op2(fast)] pub fn op_webgpu_surface_present( state: &mut OpState, - #[smi] device_rid: ResourceId, + #[smi] _device_rid: ResourceId, #[smi] surface_rid: ResourceId, ) -> Result<(), AnyError> { let instance = state.borrow::(); - let device_resource = state - .resource_table - .get::(device_rid)?; - let device = device_resource.1; let surface_resource = state.resource_table.get::(surface_rid)?; let surface = surface_resource.1; - let _ = gfx_select!(device => instance.surface_present(surface))?; + instance.surface_present(surface)?; Ok(()) } diff --git a/player/src/lib.rs b/player/src/lib.rs index 5efeff1537..8ea4e775bd 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -8,12 +8,12 @@ use wgc::device::trace; use std::{borrow::Cow, fs, path::Path}; pub trait GlobalPlay { - fn encode_commands( + fn encode_commands( &self, encoder: wgc::id::CommandEncoderId, commands: Vec, ) -> wgc::id::CommandBufferId; - fn process( + fn process( &self, device: wgc::id::DeviceId, queue: wgc::id::QueueId, @@ -24,7 +24,7 @@ pub trait GlobalPlay { } impl GlobalPlay for wgc::global::Global { - fn encode_commands( + fn encode_commands( &self, encoder: wgc::id::CommandEncoderId, commands: Vec, @@ -38,33 +38,33 @@ impl GlobalPlay for wgc::global::Global { dst_offset, size, } => self - .command_encoder_copy_buffer_to_buffer::( + .command_encoder_copy_buffer_to_buffer( encoder, src, src_offset, dst, dst_offset, size, ) .unwrap(), trace::Command::CopyBufferToTexture { src, dst, size } => self - .command_encoder_copy_buffer_to_texture::(encoder, &src, &dst, &size) + .command_encoder_copy_buffer_to_texture(encoder, &src, &dst, &size) .unwrap(), trace::Command::CopyTextureToBuffer { src, dst, size } => self - .command_encoder_copy_texture_to_buffer::(encoder, &src, &dst, &size) + .command_encoder_copy_texture_to_buffer(encoder, &src, &dst, &size) .unwrap(), trace::Command::CopyTextureToTexture { src, dst, size } => self - .command_encoder_copy_texture_to_texture::(encoder, &src, &dst, &size) + .command_encoder_copy_texture_to_texture(encoder, &src, &dst, &size) .unwrap(), trace::Command::ClearBuffer { dst, offset, size } => self - .command_encoder_clear_buffer::(encoder, dst, offset, size) + .command_encoder_clear_buffer(encoder, dst, offset, size) .unwrap(), trace::Command::ClearTexture { dst, subresource_range, } => self - .command_encoder_clear_texture::(encoder, dst, &subresource_range) + .command_encoder_clear_texture(encoder, dst, &subresource_range) .unwrap(), trace::Command::WriteTimestamp { query_set_id, query_index, } => self - .command_encoder_write_timestamp::(encoder, query_set_id, query_index) + .command_encoder_write_timestamp(encoder, query_set_id, query_index) .unwrap(), trace::Command::ResolveQuerySet { query_set_id, @@ -73,7 +73,7 @@ impl GlobalPlay for wgc::global::Global { destination, destination_offset, } => self - .command_encoder_resolve_query_set::( + .command_encoder_resolve_query_set( encoder, query_set_id, start_query, @@ -83,19 +83,19 @@ impl GlobalPlay for wgc::global::Global { ) .unwrap(), trace::Command::PushDebugGroup(marker) => self - .command_encoder_push_debug_group::(encoder, &marker) + .command_encoder_push_debug_group(encoder, &marker) .unwrap(), trace::Command::PopDebugGroup => { - self.command_encoder_pop_debug_group::(encoder).unwrap() + self.command_encoder_pop_debug_group(encoder).unwrap() } trace::Command::InsertDebugMarker(marker) => self - .command_encoder_insert_debug_marker::(encoder, &marker) + .command_encoder_insert_debug_marker(encoder, &marker) .unwrap(), trace::Command::RunComputePass { base, timestamp_writes, } => { - self.compute_pass_end_with_unresolved_commands::( + self.compute_pass_end_with_unresolved_commands( encoder, base, timestamp_writes.as_ref(), @@ -109,7 +109,7 @@ impl GlobalPlay for wgc::global::Global { timestamp_writes, occlusion_query_set_id, } => { - self.render_pass_end_with_unresolved_commands::( + self.render_pass_end_with_unresolved_commands( encoder, base, &target_colors, @@ -121,15 +121,15 @@ impl GlobalPlay for wgc::global::Global { } } } - let (cmd_buf, error) = self - .command_encoder_finish::(encoder, &wgt::CommandBufferDescriptor { label: None }); + let (cmd_buf, error) = + self.command_encoder_finish(encoder, &wgt::CommandBufferDescriptor { label: None }); if let Some(e) = error { panic!("{e}"); } cmd_buf } - fn process( + fn process( &self, device: wgc::id::DeviceId, queue: wgc::id::QueueId, @@ -150,83 +150,83 @@ impl GlobalPlay for wgc::global::Global { panic!("Unexpected Surface action: winit feature is not enabled") } Action::CreateBuffer(id, desc) => { - let (_, error) = self.device_create_buffer::(device, &desc, Some(id)); + let (_, error) = self.device_create_buffer(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::FreeBuffer(id) => { - self.buffer_destroy::(id).unwrap(); + self.buffer_destroy(id).unwrap(); } Action::DestroyBuffer(id) => { - self.buffer_drop::(id); + self.buffer_drop(id); } Action::CreateTexture(id, desc) => { - let (_, error) = self.device_create_texture::(device, &desc, Some(id)); + let (_, error) = self.device_create_texture(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::FreeTexture(id) => { - self.texture_destroy::(id).unwrap(); + self.texture_destroy(id).unwrap(); } Action::DestroyTexture(id) => { - self.texture_drop::(id); + self.texture_drop(id); } Action::CreateTextureView { id, parent_id, desc, } => { - let (_, error) = self.texture_create_view::(parent_id, &desc, Some(id)); + let (_, error) = self.texture_create_view(parent_id, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroyTextureView(id) => { - self.texture_view_drop::(id).unwrap(); + self.texture_view_drop(id).unwrap(); } Action::CreateSampler(id, desc) => { - let (_, error) = self.device_create_sampler::(device, &desc, Some(id)); + let (_, error) = self.device_create_sampler(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroySampler(id) => { - self.sampler_drop::(id); + self.sampler_drop(id); } Action::GetSurfaceTexture { id, parent_id } => { - self.surface_get_current_texture::(parent_id, Some(id)) + self.surface_get_current_texture(parent_id, Some(id)) .unwrap() .texture_id .unwrap(); } Action::CreateBindGroupLayout(id, desc) => { - let (_, error) = self.device_create_bind_group_layout::(device, &desc, Some(id)); + let (_, error) = self.device_create_bind_group_layout(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroyBindGroupLayout(id) => { - self.bind_group_layout_drop::(id); + self.bind_group_layout_drop(id); } Action::CreatePipelineLayout(id, desc) => { - let (_, error) = self.device_create_pipeline_layout::(device, &desc, Some(id)); + let (_, error) = self.device_create_pipeline_layout(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroyPipelineLayout(id) => { - self.pipeline_layout_drop::(id); + self.pipeline_layout_drop(id); } Action::CreateBindGroup(id, desc) => { - let (_, error) = self.device_create_bind_group::(device, &desc, Some(id)); + let (_, error) = self.device_create_bind_group(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroyBindGroup(id) => { - self.bind_group_drop::(id); + self.bind_group_drop(id); } Action::CreateShaderModule { id, desc, data } => { log::debug!("Creating shader from {}", data); @@ -239,14 +239,13 @@ impl GlobalPlay for wgc::global::Global { } else { panic!("Unknown shader {}", data); }; - let (_, error) = - self.device_create_shader_module::(device, &desc, source, Some(id)); + let (_, error) = self.device_create_shader_module(device, &desc, source, Some(id)); if let Some(e) = error { println!("shader compilation error:\n---{code}\n---\n{e}"); } } Action::DestroyShaderModule(id) => { - self.shader_module_drop::(id); + self.shader_module_drop(id); } Action::CreateComputePipeline { id, @@ -261,13 +260,13 @@ impl GlobalPlay for wgc::global::Global { group_ids: &ic.group_ids, }); let (_, error) = - self.device_create_compute_pipeline::(device, &desc, Some(id), implicit_ids); + self.device_create_compute_pipeline(device, &desc, Some(id), implicit_ids); if let Some(e) = error { panic!("{e}"); } } Action::DestroyComputePipeline(id) => { - self.compute_pipeline_drop::(id); + self.compute_pipeline_drop(id); } Action::CreateRenderPipeline { id, @@ -282,24 +281,24 @@ impl GlobalPlay for wgc::global::Global { group_ids: &ic.group_ids, }); let (_, error) = - self.device_create_render_pipeline::(device, &desc, Some(id), implicit_ids); + self.device_create_render_pipeline(device, &desc, Some(id), implicit_ids); if let Some(e) = error { panic!("{e}"); } } Action::DestroyRenderPipeline(id) => { - self.render_pipeline_drop::(id); + self.render_pipeline_drop(id); } Action::CreatePipelineCache { id, desc } => { - let _ = unsafe { self.device_create_pipeline_cache::(device, &desc, Some(id)) }; + let _ = unsafe { self.device_create_pipeline_cache(device, &desc, Some(id)) }; } Action::DestroyPipelineCache(id) => { - self.pipeline_cache_drop::(id); + self.pipeline_cache_drop(id); } Action::CreateRenderBundle { id, desc, base } => { let bundle = wgc::command::RenderBundleEncoder::new(&desc, device, Some(base)).unwrap(); - let (_, error) = self.render_bundle_encoder_finish::( + let (_, error) = self.render_bundle_encoder_finish( bundle, &wgt::RenderBundleDescriptor { label: desc.label }, Some(id), @@ -309,16 +308,16 @@ impl GlobalPlay for wgc::global::Global { } } Action::DestroyRenderBundle(id) => { - self.render_bundle_drop::(id); + self.render_bundle_drop(id); } Action::CreateQuerySet { id, desc } => { - let (_, error) = self.device_create_query_set::(device, &desc, Some(id)); + let (_, error) = self.device_create_query_set(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } } Action::DestroyQuerySet(id) => { - self.query_set_drop::(id); + self.query_set_drop(id); } Action::WriteBuffer { id, @@ -329,10 +328,10 @@ impl GlobalPlay for wgc::global::Global { let bin = std::fs::read(dir.join(data)).unwrap(); let size = (range.end - range.start) as usize; if queued { - self.queue_write_buffer::(queue, id, range.start, &bin) + self.queue_write_buffer(queue, id, range.start, &bin) .unwrap(); } else { - self.device_set_buffer_data::(id, range.start, &bin[..size]) + self.device_set_buffer_data(id, range.start, &bin[..size]) .unwrap(); } } @@ -343,14 +342,14 @@ impl GlobalPlay for wgc::global::Global { size, } => { let bin = std::fs::read(dir.join(data)).unwrap(); - self.queue_write_texture::(queue, &to, &bin, &layout, &size) + self.queue_write_texture(queue, &to, &bin, &layout, &size) .unwrap(); } Action::Submit(_index, ref commands) if commands.is_empty() => { - self.queue_submit::(queue, &[]).unwrap(); + self.queue_submit(queue, &[]).unwrap(); } Action::Submit(_index, commands) => { - let (encoder, error) = self.device_create_command_encoder::( + let (encoder, error) = self.device_create_command_encoder( device, &wgt::CommandEncoderDescriptor { label: None }, Some( @@ -362,8 +361,8 @@ impl GlobalPlay for wgc::global::Global { if let Some(e) = error { panic!("{e}"); } - let cmdbuf = self.encode_commands::(encoder, commands); - self.queue_submit::(queue, &[cmdbuf]).unwrap(); + let cmdbuf = self.encode_commands(encoder, commands); + self.queue_submit(queue, &[cmdbuf]).unwrap(); } } } diff --git a/tests/tests/mem_leaks.rs b/tests/tests/mem_leaks.rs index c0840f63fb..75de0776e8 100644 --- a/tests/tests/mem_leaks.rs +++ b/tests/tests/mem_leaks.rs @@ -13,7 +13,7 @@ async fn draw_test_with_reports( use wgpu::util::DeviceExt; let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.devices.num_allocated, 1); assert_eq!(report.queues.num_allocated, 1); @@ -22,7 +22,7 @@ async fn draw_test_with_reports( .create_shader_module(wgpu::include_wgsl!("./vertex_indices/draw.vert.wgsl")); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.shader_modules.num_allocated, 1); let bgl = ctx @@ -42,7 +42,7 @@ async fn draw_test_with_reports( }); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 0); assert_eq!(report.bind_groups.num_allocated, 0); assert_eq!(report.bind_group_layouts.num_allocated, 1); @@ -55,7 +55,7 @@ async fn draw_test_with_reports( }); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); let bg = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -68,7 +68,7 @@ async fn draw_test_with_reports( }); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.bind_groups.num_allocated, 1); assert_eq!(report.bind_group_layouts.num_allocated, 1); @@ -82,7 +82,7 @@ async fn draw_test_with_reports( }); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.pipeline_layouts.num_allocated, 1); assert_eq!(report.render_pipelines.num_allocated, 0); @@ -117,7 +117,7 @@ async fn draw_test_with_reports( }); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.bind_groups.num_allocated, 1); assert_eq!(report.bind_group_layouts.num_allocated, 1); @@ -129,7 +129,7 @@ async fn draw_test_with_reports( drop(shader); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.shader_modules.num_allocated, 0); assert_eq!(report.shader_modules.num_kept_from_user, 0); assert_eq!(report.textures.num_allocated, 0); @@ -157,7 +157,7 @@ async fn draw_test_with_reports( let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.texture_views.num_allocated, 1); assert_eq!(report.textures.num_allocated, 1); @@ -165,7 +165,7 @@ async fn draw_test_with_reports( drop(texture); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.texture_views.num_allocated, 1); assert_eq!(report.texture_views.num_kept_from_user, 1); @@ -177,7 +177,7 @@ async fn draw_test_with_reports( .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.command_buffers.num_allocated, 1); assert_eq!(report.buffers.num_allocated, 1); @@ -197,7 +197,7 @@ async fn draw_test_with_reports( rpass.set_bind_group(0, &bg, &[]); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.buffers.num_allocated, 1); assert_eq!(report.bind_groups.num_allocated, 1); assert_eq!(report.bind_group_layouts.num_allocated, 1); @@ -220,7 +220,7 @@ async fn draw_test_with_reports( drop(buffer); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.command_buffers.num_kept_from_user, 1); assert_eq!(report.render_pipelines.num_kept_from_user, 0); assert_eq!(report.pipeline_layouts.num_kept_from_user, 0); @@ -242,7 +242,7 @@ async fn draw_test_with_reports( // TODO: fix in https://github.com/gfx-rs/wgpu/pull/5141 // let global_report = ctx.instance.generate_report().unwrap(); - // let report = global_report.hub_report(ctx.adapter_info.backend); + // let report = global_report.hub_report(); // assert_eq!(report.command_buffers.num_allocated, 0); ctx.async_poll(wgpu::Maintain::wait_for(submit_index)) @@ -250,7 +250,7 @@ async fn draw_test_with_reports( .panic_on_timeout(); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.render_pipelines.num_allocated, 0); assert_eq!(report.bind_groups.num_allocated, 0); @@ -265,7 +265,7 @@ async fn draw_test_with_reports( drop(ctx.adapter); let global_report = ctx.instance.generate_report().unwrap(); - let report = global_report.hub_report(ctx.adapter_info.backend); + let report = global_report.hub_report(); assert_eq!(report.queues.num_kept_from_user, 0); assert_eq!(report.textures.num_kept_from_user, 0); diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 2b45302513..d8a8b32d2f 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -2,7 +2,6 @@ use crate::{ device::{ bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT, }, - hal_api::HalApi, id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId}, init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction}, pipeline::{ComputePipeline, RenderPipeline}, @@ -417,12 +416,12 @@ pub struct BindGroupEntry<'a> { /// Bindable resource and the slot to bind it to. #[derive(Clone, Debug)] -pub struct ResolvedBindGroupEntry<'a, A: HalApi> { +pub struct ResolvedBindGroupEntry<'a> { /// Slot for which binding provides resource. Corresponds to an entry of the same /// binding index in the [`BindGroupLayoutDescriptor`]. pub binding: u32, /// Resource to attach to the binding - pub resource: ResolvedBindingResource<'a, A>, + pub resource: ResolvedBindingResource<'a>, } /// Describes a group of bindings and the resources to be bound. @@ -441,15 +440,15 @@ pub struct BindGroupDescriptor<'a> { /// Describes a group of bindings and the resources to be bound. #[derive(Clone, Debug)] -pub struct ResolvedBindGroupDescriptor<'a, A: HalApi> { +pub struct ResolvedBindGroupDescriptor<'a> { /// Debug label of the bind group. /// /// This will show up in graphics debuggers for easy identification. pub label: Label<'a>, /// The [`BindGroupLayout`] that corresponds to this bind group. - pub layout: Arc>, + pub layout: Arc, /// The resources to bind to this bind group. - pub entries: Cow<'a, [ResolvedBindGroupEntry<'a, A>]>, + pub entries: Cow<'a, [ResolvedBindGroupEntry<'a>]>, } /// Describes a [`BindGroupLayout`]. @@ -468,13 +467,13 @@ pub struct BindGroupLayoutDescriptor<'a> { /// used with a specific pipeline. This constraint only happens when /// the BGLs have been derived from a pipeline without a layout. #[derive(Debug)] -pub(crate) enum ExclusivePipeline { +pub(crate) enum ExclusivePipeline { None, - Render(Weak>), - Compute(Weak>), + Render(Weak), + Compute(Weak), } -impl std::fmt::Display for ExclusivePipeline { +impl std::fmt::Display for ExclusivePipeline { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { ExclusivePipeline::None => f.write_str("None"), @@ -498,9 +497,9 @@ impl std::fmt::Display for ExclusivePipeline { /// Bind group layout. #[derive(Debug)] -pub struct BindGroupLayout { +pub struct BindGroupLayout { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, pub(crate) entries: bgl::EntryMap, /// It is very important that we know if the bind group comes from the BGL pool. /// @@ -509,14 +508,14 @@ pub struct BindGroupLayout { /// We cannot unconditionally remove from the pool, as BGLs that don't come from the pool /// (derived BGLs) must not be removed. pub(crate) origin: bgl::Origin, - pub(crate) exclusive_pipeline: OnceCell>, + pub(crate) exclusive_pipeline: OnceCell, #[allow(unused)] pub(crate) binding_count_validator: BindingTypeMaxCountValidator, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, } -impl Drop for BindGroupLayout { +impl Drop for BindGroupLayout { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); if matches!(self.origin, bgl::Origin::Pool) { @@ -530,12 +529,12 @@ impl Drop for BindGroupLayout { } } -crate::impl_resource_type_generic!(BindGroupLayout); +crate::impl_resource_type!(BindGroupLayout); crate::impl_labeled!(BindGroupLayout); crate::impl_parent_device!(BindGroupLayout); -crate::impl_storage_item_generic!(BindGroupLayout); +crate::impl_storage_item!(BindGroupLayout); -impl BindGroupLayout { +impl BindGroupLayout { pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout { self.raw.as_ref() } @@ -631,14 +630,14 @@ pub struct PipelineLayoutDescriptor<'a> { /// /// A `PipelineLayoutDescriptor` can be used to create a pipeline layout. #[derive(Debug)] -pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> { +pub struct ResolvedPipelineLayoutDescriptor<'a> { /// Debug label of the pipeline layout. /// /// This will show up in graphics debuggers for easy identification. pub label: Label<'a>, /// Bind groups that this pipeline uses. The first entry will provide all the bindings for /// "set = 0", second entry will provide all the bindings for "set = 1" etc. - pub bind_group_layouts: Cow<'a, [Arc>]>, + pub bind_group_layouts: Cow<'a, [Arc]>, /// Set of push constant ranges this pipeline uses. Each shader stage that /// uses push constants must define the range in push constant memory that /// corresponds to its single `layout(push_constant)` uniform block. @@ -650,16 +649,16 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> { } #[derive(Debug)] -pub struct PipelineLayout { +pub struct PipelineLayout { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, - pub(crate) bind_group_layouts: ArrayVec>, { hal::MAX_BIND_GROUPS }>, + pub(crate) bind_group_layouts: ArrayVec, { hal::MAX_BIND_GROUPS }>, pub(crate) push_constant_ranges: ArrayVec, } -impl Drop for PipelineLayout { +impl Drop for PipelineLayout { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -670,7 +669,7 @@ impl Drop for PipelineLayout { } } -impl PipelineLayout { +impl PipelineLayout { pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout { self.raw.as_ref() } @@ -761,10 +760,10 @@ impl PipelineLayout { } } -crate::impl_resource_type_generic!(PipelineLayout); +crate::impl_resource_type!(PipelineLayout); crate::impl_labeled!(PipelineLayout); crate::impl_parent_device!(PipelineLayout); -crate::impl_storage_item_generic!(PipelineLayout); +crate::impl_storage_item!(PipelineLayout); #[repr(C)] #[derive(Clone, Debug, Hash, Eq, PartialEq)] @@ -776,8 +775,8 @@ pub struct BufferBinding { } #[derive(Clone, Debug)] -pub struct ResolvedBufferBinding { - pub buffer: Arc>, +pub struct ResolvedBufferBinding { + pub buffer: Arc, pub offset: wgt::BufferAddress, pub size: Option, } @@ -798,13 +797,13 @@ pub enum BindingResource<'a> { // Note: Duplicated in `wgpu-rs` as `BindingResource` // They're different enough that it doesn't make sense to share a common type #[derive(Debug, Clone)] -pub enum ResolvedBindingResource<'a, A: HalApi> { - Buffer(ResolvedBufferBinding), - BufferArray(Cow<'a, [ResolvedBufferBinding]>), - Sampler(Arc>), - SamplerArray(Cow<'a, [Arc>]>), - TextureView(Arc>), - TextureViewArray(Cow<'a, [Arc>]>), +pub enum ResolvedBindingResource<'a> { + Buffer(ResolvedBufferBinding), + BufferArray(Cow<'a, [ResolvedBufferBinding]>), + Sampler(Arc), + SamplerArray(Cow<'a, [Arc]>), + TextureView(Arc), + TextureViewArray(Cow<'a, [Arc]>), } #[derive(Clone, Debug, Error)] @@ -886,23 +885,23 @@ pub(crate) fn buffer_binding_type_alignment( } #[derive(Debug)] -pub struct BindGroup { +pub struct BindGroup { pub(crate) raw: Snatchable>, - pub(crate) device: Arc>, - pub(crate) layout: Arc>, + pub(crate) device: Arc, + pub(crate) layout: Arc, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, - pub(crate) used: BindGroupStates, - pub(crate) used_buffer_ranges: Vec>, - pub(crate) used_texture_ranges: Vec>, + pub(crate) used: BindGroupStates, + pub(crate) used_buffer_ranges: Vec, + pub(crate) used_texture_ranges: Vec, pub(crate) dynamic_binding_info: Vec, /// Actual binding sizes for buffers that don't have `min_binding_size` /// specified in BGL. Listed in the order of iteration of `BGL.entries`. pub(crate) late_buffer_binding_sizes: Vec, } -impl Drop for BindGroup { +impl Drop for BindGroup { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); @@ -913,7 +912,7 @@ impl Drop for BindGroup { } } -impl BindGroup { +impl BindGroup { pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, @@ -985,10 +984,10 @@ impl BindGroup { } } -crate::impl_resource_type_generic!(BindGroup); +crate::impl_resource_type!(BindGroup); crate::impl_labeled!(BindGroup); crate::impl_parent_device!(BindGroup); -crate::impl_storage_item_generic!(BindGroup); +crate::impl_storage_item!(BindGroup); crate::impl_trackable!(BindGroup); #[derive(Clone, Debug, Error)] diff --git a/wgpu-core/src/command/bind.rs b/wgpu-core/src/command/bind.rs index 7e3d9ce9cd..620027994f 100644 --- a/wgpu-core/src/command/bind.rs +++ b/wgpu-core/src/command/bind.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use crate::{ binding_model::{BindGroup, LateMinBufferBindingSizeMismatch, PipelineLayout}, device::SHADER_STAGE_COUNT, - hal_api::HalApi, pipeline::LateSizedBufferGroup, resource::{Labeled, ResourceErrorIdent}, }; @@ -19,7 +18,6 @@ mod compat { use crate::{ binding_model::BindGroupLayout, error::MultiError, - hal_api::HalApi, resource::{Labeled, ParentDevice, ResourceErrorIdent}, }; use std::{ @@ -38,12 +36,12 @@ mod compat { } #[derive(Debug, Clone)] - struct Entry { - assigned: Option>>, - expected: Option>>, + struct Entry { + assigned: Option>, + expected: Option>, } - impl Entry { + impl Entry { fn empty() -> Self { Self { assigned: None, @@ -192,11 +190,11 @@ mod compat { } #[derive(Debug, Default)] - pub(crate) struct BoundBindGroupLayouts { - entries: ArrayVec, { hal::MAX_BIND_GROUPS }>, + pub(crate) struct BoundBindGroupLayouts { + entries: ArrayVec, } - impl BoundBindGroupLayouts { + impl BoundBindGroupLayouts { pub fn new() -> Self { Self { entries: (0..hal::MAX_BIND_GROUPS).map(|_| Entry::empty()).collect(), @@ -214,7 +212,7 @@ mod compat { pub fn update_expectations( &mut self, - expectations: &[Arc>], + expectations: &[Arc], ) -> Range { let start_index = self .entries @@ -236,7 +234,7 @@ mod compat { self.make_range(start_index) } - pub fn assign(&mut self, index: usize, value: Arc>) -> Range { + pub fn assign(&mut self, index: usize, value: Arc) -> Range { self.entries[index].assigned = Some(value); self.make_range(index) } @@ -283,9 +281,9 @@ struct LateBufferBinding { bound_size: wgt::BufferAddress, } -#[derive(Debug)] -pub(super) struct EntryPayload { - pub(super) group: Option>>, +#[derive(Debug, Default)] +pub(super) struct EntryPayload { + pub(super) group: Option>, pub(super) dynamic_offsets: Vec, late_buffer_bindings: Vec, /// Since `LateBufferBinding` may contain information about the bindings @@ -293,18 +291,7 @@ pub(super) struct EntryPayload { pub(super) late_bindings_effective_count: usize, } -impl Default for EntryPayload { - fn default() -> Self { - Self { - group: None, - dynamic_offsets: Default::default(), - late_buffer_bindings: Default::default(), - late_bindings_effective_count: Default::default(), - } - } -} - -impl EntryPayload { +impl EntryPayload { fn reset(&mut self) { self.group = None; self.dynamic_offsets.clear(); @@ -314,13 +301,13 @@ impl EntryPayload { } #[derive(Debug, Default)] -pub(super) struct Binder { - pub(super) pipeline_layout: Option>>, - manager: compat::BoundBindGroupLayouts, - payloads: [EntryPayload; hal::MAX_BIND_GROUPS], +pub(super) struct Binder { + pub(super) pipeline_layout: Option>, + manager: compat::BoundBindGroupLayouts, + payloads: [EntryPayload; hal::MAX_BIND_GROUPS], } -impl Binder { +impl Binder { pub(super) fn new() -> Self { Self { pipeline_layout: None, @@ -338,9 +325,9 @@ impl Binder { pub(super) fn change_pipeline_layout<'a>( &'a mut self, - new: &Arc>, + new: &Arc, late_sized_buffer_groups: &[LateSizedBufferGroup], - ) -> (usize, &'a [EntryPayload]) { + ) -> (usize, &'a [EntryPayload]) { let old_id_opt = self.pipeline_layout.replace(new.clone()); let mut bind_range = self.manager.update_expectations(&new.bind_group_layouts); @@ -380,9 +367,9 @@ impl Binder { pub(super) fn assign_group<'a>( &'a mut self, index: usize, - bind_group: &Arc>, + bind_group: &Arc, offsets: &[wgt::DynamicOffset], - ) -> &'a [EntryPayload] { + ) -> &'a [EntryPayload] { let payload = &mut self.payloads[index]; payload.group = Some(bind_group.clone()); payload.dynamic_offsets.clear(); @@ -412,7 +399,7 @@ impl Binder { &self.payloads[bind_range] } - pub(super) fn list_active<'a>(&'a self) -> impl Iterator>> + '_ { + pub(super) fn list_active<'a>(&'a self) -> impl Iterator> + '_ { let payloads = &self.payloads; self.manager .list_active() diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index a8a3528647..56f7d551b0 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -88,7 +88,6 @@ use crate::{ AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext, SHADER_STAGE_COUNT, }, - hal_api::HalApi, hub::Hub, id, init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction}, @@ -110,8 +109,8 @@ use super::{ }; /// -fn validate_draw( - vertex: &[Option>], +fn validate_draw( + vertex: &[Option], step: &[VertexStep], first_vertex: u32, vertex_count: u32, @@ -151,10 +150,10 @@ fn validate_draw( } // See https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-drawindexed -fn validate_indexed_draw( - vertex: &[Option>], +fn validate_indexed_draw( + vertex: &[Option], step: &[VertexStep], - index_state: &IndexState, + index_state: &IndexState, first_index: u32, index_count: u32, first_instance: u32, @@ -339,12 +338,12 @@ impl RenderBundleEncoder { /// and accumulate buffer and texture initialization actions. /// /// [`ExecuteBundle`]: RenderCommand::ExecuteBundle - pub(crate) fn finish( + pub(crate) fn finish( self, desc: &RenderBundleDescriptor, - device: &Arc>, - hub: &Hub, - ) -> Result>, RenderBundleError> { + device: &Arc, + hub: &Hub, + ) -> Result, RenderBundleError> { let scope = PassErrorScope::Bundle; device.check_is_valid().map_pass_err(scope)?; @@ -577,9 +576,9 @@ impl RenderBundleEncoder { } } -fn set_bind_group( - state: &mut State, - bind_group_guard: &crate::lock::RwLockReadGuard>>, +fn set_bind_group( + state: &mut State, + bind_group_guard: &crate::lock::RwLockReadGuard>, dynamic_offsets: &[u32], index: u32, num_dynamic_offsets: usize, @@ -622,9 +621,9 @@ fn set_bind_group( Ok(()) } -fn set_pipeline( - state: &mut State, - pipeline_guard: &crate::lock::RwLockReadGuard>>, +fn set_pipeline( + state: &mut State, + pipeline_guard: &crate::lock::RwLockReadGuard>, context: &RenderPassContext, is_depth_read_only: bool, is_stencil_read_only: bool, @@ -665,9 +664,9 @@ fn set_pipeline( Ok(()) } -fn set_index_buffer( - state: &mut State, - buffer_guard: &crate::lock::RwLockReadGuard>>, +fn set_index_buffer( + state: &mut State, + buffer_guard: &crate::lock::RwLockReadGuard>, buffer_id: id::Id, index_format: wgt::IndexFormat, offset: u64, @@ -700,9 +699,9 @@ fn set_index_buffer( Ok(()) } -fn set_vertex_buffer( - state: &mut State, - buffer_guard: &crate::lock::RwLockReadGuard>>, +fn set_vertex_buffer( + state: &mut State, + buffer_guard: &crate::lock::RwLockReadGuard>, slot: u32, buffer_id: id::Id, offset: u64, @@ -744,8 +743,8 @@ fn set_vertex_buffer( Ok(()) } -fn set_push_constant( - state: &mut State, +fn set_push_constant( + state: &mut State, stages: wgt::ShaderStages, offset: u32, size_bytes: u32, @@ -769,8 +768,8 @@ fn set_push_constant( Ok(()) } -fn draw( - state: &mut State, +fn draw( + state: &mut State, dynamic_offsets: &[u32], vertex_count: u32, instance_count: u32, @@ -802,8 +801,8 @@ fn draw( Ok(()) } -fn draw_indexed( - state: &mut State, +fn draw_indexed( + state: &mut State, dynamic_offsets: &[u32], index_count: u32, instance_count: u32, @@ -843,10 +842,10 @@ fn draw_indexed( Ok(()) } -fn multi_draw_indirect( - state: &mut State, +fn multi_draw_indirect( + state: &mut State, dynamic_offsets: &[u32], - buffer_guard: &crate::lock::RwLockReadGuard>>, + buffer_guard: &crate::lock::RwLockReadGuard>, buffer_id: id::Id, offset: u64, indexed: bool, @@ -923,16 +922,16 @@ pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor>; // The plan is to back it by an actual Vulkan secondary buffer, D3D12 Bundle, // or Metal indirect command buffer. #[derive(Debug)] -pub struct RenderBundle { +pub struct RenderBundle { // Normalized command stream. It can be executed verbatim, // without re-binding anything on the pipeline change. - base: BasePass>, + base: BasePass, pub(super) is_depth_read_only: bool, pub(super) is_stencil_read_only: bool, - pub(crate) device: Arc>, - pub(crate) used: RenderBundleScope, - pub(super) buffer_memory_init_actions: Vec>, - pub(super) texture_memory_init_actions: Vec>, + pub(crate) device: Arc, + pub(crate) used: RenderBundleScope, + pub(super) buffer_memory_init_actions: Vec, + pub(super) texture_memory_init_actions: Vec, pub(super) context: RenderPassContext, /// The `label` from the descriptor used to create the resource. label: String, @@ -940,18 +939,18 @@ pub struct RenderBundle { discard_hal_labels: bool, } -impl Drop for RenderBundle { +impl Drop for RenderBundle { fn drop(&mut self) { resource_log!("Drop {}", self.error_ident()); } } #[cfg(send_sync)] -unsafe impl Send for RenderBundle {} +unsafe impl Send for RenderBundle {} #[cfg(send_sync)] -unsafe impl Sync for RenderBundle {} +unsafe impl Sync for RenderBundle {} -impl RenderBundle { +impl RenderBundle { /// Actually encode the contents into a native command buffer. /// /// This is partially duplicating the logic of `render_pass_end`. @@ -967,7 +966,7 @@ impl RenderBundle { snatch_guard: &SnatchGuard, ) -> Result<(), ExecutionError> { let mut offsets = self.base.dynamic_offsets.as_slice(); - let mut pipeline_layout = None::>>; + let mut pipeline_layout = None::>; if !self.discard_hal_labels { if let Some(ref label) = self.base.label { unsafe { raw.begin_debug_marker(label) }; @@ -1146,10 +1145,10 @@ impl RenderBundle { } } -crate::impl_resource_type_generic!(RenderBundle); +crate::impl_resource_type!(RenderBundle); crate::impl_labeled!(RenderBundle); crate::impl_parent_device!(RenderBundle); -crate::impl_storage_item_generic!(RenderBundle); +crate::impl_storage_item!(RenderBundle); crate::impl_trackable!(RenderBundle); /// A render bundle's current index buffer state. @@ -1158,14 +1157,14 @@ crate::impl_trackable!(RenderBundle); /// and calls [`State::flush_index`] before any indexed draw command to produce /// a `SetIndexBuffer` command if one is necessary. #[derive(Debug)] -struct IndexState { - buffer: Arc>, +struct IndexState { + buffer: Arc, format: wgt::IndexFormat, range: Range, is_dirty: bool, } -impl IndexState { +impl IndexState { /// Return the number of entries in the current index buffer. /// /// Panic if no index buffer has been set. @@ -1180,7 +1179,7 @@ impl IndexState { /// Generate a `SetIndexBuffer` command to prepare for an indexed draw /// command, if needed. - fn flush(&mut self) -> Option> { + fn flush(&mut self) -> Option { if self.is_dirty { self.is_dirty = false; Some(ArcRenderCommand::SetIndexBuffer { @@ -1205,14 +1204,14 @@ impl IndexState { /// /// [`flush`]: IndexState::flush #[derive(Debug)] -struct VertexState { - buffer: Arc>, +struct VertexState { + buffer: Arc, range: Range, is_dirty: bool, } -impl VertexState { - fn new(buffer: Arc>, range: Range) -> Self { +impl VertexState { + fn new(buffer: Arc, range: Range) -> Self { Self { buffer, range, @@ -1223,7 +1222,7 @@ impl VertexState { /// Generate a `SetVertexBuffer` command for this slot, if necessary. /// /// `slot` is the index of the vertex buffer slot that `self` tracks. - fn flush(&mut self, slot: u32) -> Option> { + fn flush(&mut self, slot: u32) -> Option { if self.is_dirty { self.is_dirty = false; Some(ArcRenderCommand::SetVertexBuffer { @@ -1240,9 +1239,9 @@ impl VertexState { /// A bind group that has been set at a particular index during render bundle encoding. #[derive(Debug)] -struct BindState { +struct BindState { /// The id of the bind group set at this index. - bind_group: Arc>, + bind_group: Arc, /// The range of dynamic offsets for this bind group, in the original /// command stream's `BassPass::dynamic_offsets` array. @@ -1254,9 +1253,9 @@ struct BindState { } /// The bundle's current pipeline, and some cached information needed for validation. -struct PipelineState { +struct PipelineState { /// The pipeline - pipeline: Arc>, + pipeline: Arc, /// How this pipeline's vertex shader traverses each vertex buffer, indexed /// by vertex buffer slot number. @@ -1270,8 +1269,8 @@ struct PipelineState { used_bind_groups: usize, } -impl PipelineState { - fn new(pipeline: &Arc>) -> Self { +impl PipelineState { + fn new(pipeline: &Arc) -> Self { Self { pipeline: pipeline.clone(), steps: pipeline.vertex_steps.to_vec(), @@ -1287,7 +1286,7 @@ impl PipelineState { /// Return a sequence of commands to zero the push constant ranges this /// pipeline uses. If no initialization is necessary, return `None`. - fn zero_push_constants(&self) -> Option>> { + fn zero_push_constants(&self) -> Option> { if !self.push_constant_ranges.is_empty() { let nonoverlapping_ranges = super::bind::compute_nonoverlapping_ranges(&self.push_constant_ranges); @@ -1318,22 +1317,22 @@ impl PipelineState { /// /// [`SetBindGroup`]: RenderCommand::SetBindGroup /// [`SetIndexBuffer`]: RenderCommand::SetIndexBuffer -struct State { +struct State { /// Resources used by this bundle. This will become [`RenderBundle::used`]. - trackers: RenderBundleScope, + trackers: RenderBundleScope, /// The currently set pipeline, if any. - pipeline: Option>, + pipeline: Option, /// The bind group set at each index, if any. - bind: ArrayVec>, { hal::MAX_BIND_GROUPS }>, + bind: ArrayVec, { hal::MAX_BIND_GROUPS }>, /// The state of each vertex buffer slot. - vertex: ArrayVec>, { hal::MAX_VERTEX_BUFFERS }>, + vertex: ArrayVec, { hal::MAX_VERTEX_BUFFERS }>, /// The current index buffer, if one has been set. We flush this state /// before indexed draw commands. - index: Option>, + index: Option, /// Dynamic offset values used by the cleaned-up command sequence. /// @@ -1343,16 +1342,16 @@ struct State { /// [`dynamic_offsets`]: BasePass::dynamic_offsets flat_dynamic_offsets: Vec, - device: Arc>, - commands: Vec>, - buffer_memory_init_actions: Vec>, - texture_memory_init_actions: Vec>, + device: Arc, + commands: Vec, + buffer_memory_init_actions: Vec, + texture_memory_init_actions: Vec, next_dynamic_offset: usize, } -impl State { +impl State { /// Return the current pipeline state. Return an error if none is set. - fn pipeline(&self) -> Result<&PipelineState, RenderBundleErrorInner> { + fn pipeline(&self) -> Result<&PipelineState, RenderBundleErrorInner> { self.pipeline .as_ref() .ok_or(DrawError::MissingPipeline.into()) @@ -1368,7 +1367,7 @@ impl State { fn set_bind_group( &mut self, slot: u32, - bind_group: &Arc>, + bind_group: &Arc, dynamic_offsets: Range, ) { // If this call wouldn't actually change this index's state, we can @@ -1407,7 +1406,7 @@ impl State { /// /// - Changing the push constant ranges at all requires re-establishing /// all bind groups. - fn invalidate_bind_groups(&mut self, new: &PipelineState, layout: &PipelineLayout) { + fn invalidate_bind_groups(&mut self, new: &PipelineState, layout: &PipelineLayout) { match self.pipeline { None => { // Establishing entirely new pipeline state. @@ -1441,7 +1440,7 @@ impl State { /// Set the bundle's current index buffer and its associated parameters. fn set_index_buffer( &mut self, - buffer: Arc>, + buffer: Arc, format: wgt::IndexFormat, range: Range, ) { diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 487bdf756b..944dd40af4 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -8,7 +8,6 @@ use crate::{ device::DeviceError, get_lowest_common_denom, global::Global, - hal_api::HalApi, id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{ @@ -79,7 +78,7 @@ whereas subesource range specified start {subresource_base_array_layer} and coun } impl Global { - pub fn command_encoder_clear_buffer( + pub fn command_encoder_clear_buffer( &self, command_encoder_id: CommandEncoderId, dst: BufferId, @@ -89,7 +88,7 @@ impl Global { profiling::scope!("CommandEncoder::clear_buffer"); api_log!("CommandEncoder::clear_buffer {dst:?}"); - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -172,7 +171,7 @@ impl Global { Ok(()) } - pub fn command_encoder_clear_texture( + pub fn command_encoder_clear_texture( &self, command_encoder_id: CommandEncoderId, dst: TextureId, @@ -181,7 +180,7 @@ impl Global { profiling::scope!("CommandEncoder::clear_texture"); api_log!("CommandEncoder::clear_texture {dst:?}"); - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -268,8 +267,8 @@ impl Global { } } -pub(crate) fn clear_texture>( - dst_texture: &Arc>, +pub(crate) fn clear_texture( + dst_texture: &Arc, range: TextureInitRange, encoder: &mut dyn hal::DynCommandEncoder, texture_tracker: &mut T, @@ -440,8 +439,8 @@ fn clear_texture_via_buffer_copies( } } -fn clear_texture_via_render_passes( - dst_texture: &Texture, +fn clear_texture_via_render_passes( + dst_texture: &Texture, range: TextureInitRange, is_color: bool, encoder: &mut dyn hal::DynCommandEncoder, @@ -461,7 +460,7 @@ fn clear_texture_via_render_passes( let (color_attachments, depth_stencil_attachment) = if is_color { color_attachments_tmp = [Some(hal::ColorAttachment { target: hal::Attachment { - view: Texture::::get_clear_view( + view: Texture::get_clear_view( &dst_texture.clear_mode, &dst_texture.desc, mip_level, @@ -479,7 +478,7 @@ fn clear_texture_via_render_passes( &[][..], Some(hal::DepthStencilAttachment { target: hal::Attachment { - view: Texture::::get_clear_view( + view: Texture::get_clear_view( &dst_texture.clear_mode, &dst_texture.desc, mip_level, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index a23370527f..93e7c15168 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -13,7 +13,6 @@ use crate::{ }, device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures}, global::Global, - hal_api::HalApi, hal_label, id, init_tracker::{BufferInitTrackerAction, MemoryInitKind}, pipeline::ComputePipeline, @@ -34,28 +33,28 @@ use std::{fmt, mem, str}; use super::{bind::BinderError, memory_init::CommandBufferTextureMemoryActions, DynComputePass}; -pub struct ComputePass { +pub struct ComputePass { /// All pass data & records is stored here. /// /// If this is `None`, the pass is in the 'ended' state and can no longer be used. /// Any attempt to record more commands will result in a validation error. - base: Option>>, + base: Option>, /// Parent command buffer that this pass records commands into. /// /// If it is none, this pass is invalid and any operation on it will return an error. - parent: Option>>, + parent: Option>, - timestamp_writes: Option>, + timestamp_writes: Option, // Resource binding dedupe state. current_bind_groups: BindGroupStateChange, current_pipeline: StateChange, } -impl ComputePass { +impl ComputePass { /// If the parent command buffer is invalid, the returned pass will be invalid. - fn new(parent: Option>>, desc: ArcComputePassDescriptor) -> Self { + fn new(parent: Option>, desc: ArcComputePassDescriptor) -> Self { let ArcComputePassDescriptor { label, timestamp_writes, @@ -79,7 +78,7 @@ impl ComputePass { fn base_mut<'a>( &'a mut self, scope: PassErrorScope, - ) -> Result<&'a mut BasePass>, ComputePassError> { + ) -> Result<&'a mut BasePass, ComputePassError> { self.base .as_mut() .ok_or(ComputePassErrorInner::PassEnded) @@ -87,7 +86,7 @@ impl ComputePass { } } -impl fmt::Debug for ComputePass { +impl fmt::Debug for ComputePass { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.parent { Some(ref cmd_buf) => write!(f, "ComputePass {{ parent: {} }}", cmd_buf.error_ident()), @@ -103,10 +102,10 @@ pub struct ComputePassDescriptor<'a> { pub timestamp_writes: Option<&'a PassTimestampWrites>, } -struct ArcComputePassDescriptor<'a, A: HalApi> { +struct ArcComputePassDescriptor<'a> { pub label: &'a Label<'a>, /// Defines where and when timestamp values will be written for this pass. - pub timestamp_writes: Option>, + pub timestamp_writes: Option, } #[derive(Clone, Debug, Error)] @@ -200,36 +199,36 @@ where } } -struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { - binder: Binder, - pipeline: Option>>, - scope: UsageScope<'scope, A>, +struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> { + binder: Binder, + pipeline: Option>, + scope: UsageScope<'scope>, debug_scope_depth: u32, snatch_guard: SnatchGuard<'snatch_guard>, - device: &'cmd_buf Arc>, + device: &'cmd_buf Arc, raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, - tracker: &'cmd_buf mut Tracker, - buffer_memory_init_actions: &'cmd_buf mut Vec>, - texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions, + tracker: &'cmd_buf mut Tracker, + buffer_memory_init_actions: &'cmd_buf mut Vec, + texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions, temp_offsets: Vec, dynamic_offset_count: usize, string_offset: usize, - active_query: Option<(Arc>, u32)>, + active_query: Option<(Arc, u32)>, - intermediate_trackers: Tracker, + intermediate_trackers: Tracker, /// Immediate texture inits required because of prior discards. Need to /// be inserted before texture reads. - pending_discard_init_fixups: SurfacesInDiscardState, + pending_discard_init_fixups: SurfacesInDiscardState, } -impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> - State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A> +impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> + State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> { fn is_ready(&self) -> Result<(), DispatchError> { if let Some(pipeline) = self.pipeline.as_ref() { @@ -285,12 +284,12 @@ impl Global { /// Any operation on an invalid pass will return an error. /// /// If successful, puts the encoder into the [`CommandEncoderStatus::Locked`] state. - pub fn command_encoder_create_compute_pass( + pub fn command_encoder_create_compute_pass( &self, encoder_id: id::CommandEncoderId, desc: &ComputePassDescriptor<'_>, - ) -> (ComputePass, Option) { - let hub = A::hub(self); + ) -> (ComputePass, Option) { + let hub = &self.hub; let mut arc_desc = ArcComputePassDescriptor { label: &desc.label, @@ -333,19 +332,16 @@ impl Global { /// /// If creation fails, an invalid pass is returned. /// Any operation on an invalid pass will return an error. - pub fn command_encoder_create_compute_pass_dyn( + pub fn command_encoder_create_compute_pass_dyn( &self, encoder_id: id::CommandEncoderId, desc: &ComputePassDescriptor, ) -> (Box, Option) { - let (pass, err) = self.command_encoder_create_compute_pass::(encoder_id, desc); + let (pass, err) = self.command_encoder_create_compute_pass(encoder_id, desc); (Box::new(pass), err) } - pub fn compute_pass_end( - &self, - pass: &mut ComputePass, - ) -> Result<(), ComputePassError> { + pub fn compute_pass_end(&self, pass: &mut ComputePass) -> Result<(), ComputePassError> { let scope = PassErrorScope::Pass; let cmd_buf = pass @@ -366,13 +362,13 @@ impl Global { #[doc(hidden)] #[cfg(any(feature = "serde", feature = "replay"))] - pub fn compute_pass_end_with_unresolved_commands( + pub fn compute_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, base: BasePass, timestamp_writes: Option<&PassTimestampWrites>, ) -> Result<(), ComputePassError> { - let hub = A::hub(self); + let hub = &self.hub; let scope = PassErrorScope::Pass; let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) { @@ -400,7 +396,7 @@ impl Global { } let commands = - super::ComputeCommand::resolve_compute_command_ids(A::hub(self), &base.commands)?; + super::ComputeCommand::resolve_compute_command_ids(&self.hub, &base.commands)?; let timestamp_writes = if let Some(tw) = timestamp_writes { Some(ArcPassTimestampWrites { @@ -416,7 +412,7 @@ impl Global { None }; - self.compute_pass_end_impl::( + self.compute_pass_end_impl( &cmd_buf, BasePass { label: base.label, @@ -429,11 +425,11 @@ impl Global { ) } - fn compute_pass_end_impl( + fn compute_pass_end_impl( &self, - cmd_buf: &CommandBuffer, - base: BasePass>, - mut timestamp_writes: Option>, + cmd_buf: &CommandBuffer, + base: BasePass, + mut timestamp_writes: Option, ) -> Result<(), ComputePassError> { profiling::scope!("CommandEncoder::run_compute_pass"); let pass_scope = PassErrorScope::Pass; @@ -660,13 +656,13 @@ impl Global { } } -fn set_bind_group( - state: &mut State, - cmd_buf: &CommandBuffer, +fn set_bind_group( + state: &mut State, + cmd_buf: &CommandBuffer, dynamic_offsets: &[DynamicOffset], index: u32, num_dynamic_offsets: usize, - bind_group: Arc>, + bind_group: Arc, ) -> Result<(), ComputePassErrorInner> { bind_group.same_device_as(cmd_buf)?; @@ -727,10 +723,10 @@ fn set_bind_group( Ok(()) } -fn set_pipeline( - state: &mut State, - cmd_buf: &CommandBuffer, - pipeline: Arc>, +fn set_pipeline( + state: &mut State, + cmd_buf: &CommandBuffer, + pipeline: Arc, ) -> Result<(), ComputePassErrorInner> { pipeline.same_device_as(cmd_buf)?; @@ -789,8 +785,8 @@ fn set_pipeline( Ok(()) } -fn set_push_constant( - state: &mut State, +fn set_push_constant( + state: &mut State, push_constant_data: &[u32], offset: u32, size_bytes: u32, @@ -826,10 +822,7 @@ fn set_push_constant( Ok(()) } -fn dispatch( - state: &mut State, - groups: [u32; 3], -) -> Result<(), ComputePassErrorInner> { +fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorInner> { state.is_ready()?; state.flush_states(None)?; @@ -854,10 +847,10 @@ fn dispatch( Ok(()) } -fn dispatch_indirect( - state: &mut State, - cmd_buf: &CommandBuffer, - buffer: Arc>, +fn dispatch_indirect( + state: &mut State, + cmd_buf: &CommandBuffer, + buffer: Arc, offset: u64, ) -> Result<(), ComputePassErrorInner> { buffer.same_device_as(cmd_buf)?; @@ -902,7 +895,7 @@ fn dispatch_indirect( Ok(()) } -fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) { +fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) { state.debug_scope_depth += 1; if !state .device @@ -918,7 +911,7 @@ fn push_debug_group(state: &mut State, string_data: &[u8], len: us state.string_offset += len; } -fn pop_debug_group(state: &mut State) -> Result<(), ComputePassErrorInner> { +fn pop_debug_group(state: &mut State) -> Result<(), ComputePassErrorInner> { if state.debug_scope_depth == 0 { return Err(ComputePassErrorInner::InvalidPopDebugGroup); } @@ -935,7 +928,7 @@ fn pop_debug_group(state: &mut State) -> Result<(), ComputePassErr Ok(()) } -fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) { +fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) { if !state .device .instance_flags @@ -948,10 +941,10 @@ fn insert_debug_marker(state: &mut State, string_data: &[u8], len: state.string_offset += len; } -fn write_timestamp( - state: &mut State, - cmd_buf: &CommandBuffer, - query_set: Arc>, +fn write_timestamp( + state: &mut State, + cmd_buf: &CommandBuffer, + query_set: Arc, query_index: u32, ) -> Result<(), ComputePassErrorInner> { query_set.same_device_as(cmd_buf)?; @@ -968,9 +961,9 @@ fn write_timestamp( // Recording a compute pass. impl Global { - pub fn compute_pass_set_bind_group( + pub fn compute_pass_set_bind_group( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, index: u32, bind_group_id: id::BindGroupId, offsets: &[DynamicOffset], @@ -993,7 +986,7 @@ impl Global { return Ok(()); } - let hub = A::hub(self); + let hub = &self.hub; let bind_group = hub .bind_groups .get(bind_group_id) @@ -1009,9 +1002,9 @@ impl Global { Ok(()) } - pub fn compute_pass_set_pipeline( + pub fn compute_pass_set_pipeline( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, pipeline_id: id::ComputePipelineId, ) -> Result<(), ComputePassError> { let redundant = pass.current_pipeline.set_and_check_redundant(pipeline_id); @@ -1024,7 +1017,7 @@ impl Global { return Ok(()); } - let hub = A::hub(self); + let hub = &self.hub; let pipeline = hub .compute_pipelines .get(pipeline_id) @@ -1036,9 +1029,9 @@ impl Global { Ok(()) } - pub fn compute_pass_set_push_constants( + pub fn compute_pass_set_push_constants( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, offset: u32, data: &[u8], ) -> Result<(), ComputePassError> { @@ -1064,7 +1057,7 @@ impl Global { .map(|arr| u32::from_ne_bytes([arr[0], arr[1], arr[2], arr[3]])), ); - base.commands.push(ArcComputeCommand::::SetPushConstant { + base.commands.push(ArcComputeCommand::SetPushConstant { offset, size_bytes: data.len() as u32, values_offset: value_offset, @@ -1073,9 +1066,9 @@ impl Global { Ok(()) } - pub fn compute_pass_dispatch_workgroups( + pub fn compute_pass_dispatch_workgroups( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, groups_x: u32, groups_y: u32, groups_z: u32, @@ -1083,20 +1076,19 @@ impl Global { let scope = PassErrorScope::Dispatch { indirect: false }; let base = pass.base_mut(scope)?; - base.commands.push(ArcComputeCommand::::Dispatch([ - groups_x, groups_y, groups_z, - ])); + base.commands + .push(ArcComputeCommand::Dispatch([groups_x, groups_y, groups_z])); Ok(()) } - pub fn compute_pass_dispatch_workgroups_indirect( + pub fn compute_pass_dispatch_workgroups_indirect( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, buffer_id: id::BufferId, offset: BufferAddress, ) -> Result<(), ComputePassError> { - let hub = A::hub(self); + let hub = &self.hub; let scope = PassErrorScope::Dispatch { indirect: true }; let base = pass.base_mut(scope)?; @@ -1107,14 +1099,14 @@ impl Global { .map_pass_err(scope)?; base.commands - .push(ArcComputeCommand::::DispatchIndirect { buffer, offset }); + .push(ArcComputeCommand::DispatchIndirect { buffer, offset }); Ok(()) } - pub fn compute_pass_push_debug_group( + pub fn compute_pass_push_debug_group( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, label: &str, color: u32, ) -> Result<(), ComputePassError> { @@ -1123,7 +1115,7 @@ impl Global { let bytes = label.as_bytes(); base.string_data.extend_from_slice(bytes); - base.commands.push(ArcComputeCommand::::PushDebugGroup { + base.commands.push(ArcComputeCommand::PushDebugGroup { color, len: bytes.len(), }); @@ -1131,20 +1123,20 @@ impl Global { Ok(()) } - pub fn compute_pass_pop_debug_group( + pub fn compute_pass_pop_debug_group( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, ) -> Result<(), ComputePassError> { let base = pass.base_mut(PassErrorScope::PopDebugGroup)?; - base.commands.push(ArcComputeCommand::::PopDebugGroup); + base.commands.push(ArcComputeCommand::PopDebugGroup); Ok(()) } - pub fn compute_pass_insert_debug_marker( + pub fn compute_pass_insert_debug_marker( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, label: &str, color: u32, ) -> Result<(), ComputePassError> { @@ -1153,25 +1145,24 @@ impl Global { let bytes = label.as_bytes(); base.string_data.extend_from_slice(bytes); - base.commands - .push(ArcComputeCommand::::InsertDebugMarker { - color, - len: bytes.len(), - }); + base.commands.push(ArcComputeCommand::InsertDebugMarker { + color, + len: bytes.len(), + }); Ok(()) } - pub fn compute_pass_write_timestamp( + pub fn compute_pass_write_timestamp( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, query_set_id: id::QuerySetId, query_index: u32, ) -> Result<(), ComputePassError> { let scope = PassErrorScope::WriteTimestamp; let base = pass.base_mut(scope)?; - let hub = A::hub(self); + let hub = &self.hub; let query_set = hub .query_sets .get(query_set_id) @@ -1186,16 +1177,16 @@ impl Global { Ok(()) } - pub fn compute_pass_begin_pipeline_statistics_query( + pub fn compute_pass_begin_pipeline_statistics_query( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, query_set_id: id::QuerySetId, query_index: u32, ) -> Result<(), ComputePassError> { let scope = PassErrorScope::BeginPipelineStatisticsQuery; let base = pass.base_mut(scope)?; - let hub = A::hub(self); + let hub = &self.hub; let query_set = hub .query_sets .get(query_set_id) @@ -1211,14 +1202,14 @@ impl Global { Ok(()) } - pub fn compute_pass_end_pipeline_statistics_query( + pub fn compute_pass_end_pipeline_statistics_query( &self, - pass: &mut ComputePass, + pass: &mut ComputePass, ) -> Result<(), ComputePassError> { let scope = PassErrorScope::EndPipelineStatisticsQuery; let base = pass.base_mut(scope)?; base.commands - .push(ArcComputeCommand::::EndPipelineStatisticsQuery); + .push(ArcComputeCommand::EndPipelineStatisticsQuery); Ok(()) } diff --git a/wgpu-core/src/command/compute_command.rs b/wgpu-core/src/command/compute_command.rs index 761827b85a..e16487b7ea 100644 --- a/wgpu-core/src/command/compute_command.rs +++ b/wgpu-core/src/command/compute_command.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use crate::{ binding_model::BindGroup, - hal_api::HalApi, id, pipeline::ComputePipeline, resource::{Buffer, QuerySet}, @@ -71,10 +70,10 @@ pub enum ComputeCommand { impl ComputeCommand { /// Resolves all ids in a list of commands into the corresponding resource Arc. #[cfg(any(feature = "serde", feature = "replay"))] - pub fn resolve_compute_command_ids( - hub: &crate::hub::Hub, + pub fn resolve_compute_command_ids( + hub: &crate::hub::Hub, commands: &[ComputeCommand], - ) -> Result>, super::ComputePassError> { + ) -> Result, super::ComputePassError> { use super::{ComputePassError, ComputePassErrorInner, PassErrorScope}; let buffers_guard = hub.buffers.read(); @@ -82,9 +81,9 @@ impl ComputeCommand { let query_set_guard = hub.query_sets.read(); let pipelines_guard = hub.compute_pipelines.read(); - let resolved_commands: Vec> = commands + let resolved_commands: Vec = commands .iter() - .map(|c| -> Result, ComputePassError> { + .map(|c| -> Result { Ok(match *c { ComputeCommand::SetBindGroup { index, @@ -182,14 +181,14 @@ impl ComputeCommand { /// Equivalent to `ComputeCommand` but the Ids resolved into resource Arcs. #[derive(Clone, Debug)] -pub enum ArcComputeCommand { +pub enum ArcComputeCommand { SetBindGroup { index: u32, num_dynamic_offsets: usize, - bind_group: Arc>, + bind_group: Arc, }, - SetPipeline(Arc>), + SetPipeline(Arc), /// Set a range of push constants to values stored in `push_constant_data`. SetPushConstant { @@ -211,7 +210,7 @@ pub enum ArcComputeCommand { Dispatch([u32; 3]), DispatchIndirect { - buffer: Arc>, + buffer: Arc, offset: wgt::BufferAddress, }, @@ -228,12 +227,12 @@ pub enum ArcComputeCommand { }, WriteTimestamp { - query_set: Arc>, + query_set: Arc, query_index: u32, }, BeginPipelineStatisticsQuery { - query_set: Arc>, + query_set: Arc, query_index: u32, }, diff --git a/wgpu-core/src/command/dyn_compute_pass.rs b/wgpu-core/src/command/dyn_compute_pass.rs index ea15e2667d..273feaddf7 100644 --- a/wgpu-core/src/command/dyn_compute_pass.rs +++ b/wgpu-core/src/command/dyn_compute_pass.rs @@ -1,6 +1,6 @@ use wgt::WasmNotSendSync; -use crate::{global, hal_api::HalApi, id}; +use crate::{global, id}; use super::{ComputePass, ComputePassError}; @@ -74,7 +74,7 @@ pub trait DynComputePass: std::fmt::Debug + WasmNotSendSync { fn label(&self) -> Option<&str>; } -impl DynComputePass for ComputePass { +impl DynComputePass for ComputePass { fn set_bind_group( &mut self, context: &global::Global, diff --git a/wgpu-core/src/command/dyn_render_pass.rs b/wgpu-core/src/command/dyn_render_pass.rs index 7ad79262b3..d20ca09780 100644 --- a/wgpu-core/src/command/dyn_render_pass.rs +++ b/wgpu-core/src/command/dyn_render_pass.rs @@ -1,6 +1,6 @@ use wgt::WasmNotSendSync; -use crate::{global, hal_api::HalApi, id}; +use crate::{global, id}; use super::{RenderPass, RenderPassError}; @@ -178,7 +178,7 @@ pub trait DynRenderPass: std::fmt::Debug + WasmNotSendSync { fn label(&self) -> Option<&str>; } -impl DynRenderPass for RenderPass { +impl DynRenderPass for RenderPass { fn set_index_buffer( &mut self, context: &global::Global, diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 7e672393f1..a4711998b2 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -2,7 +2,6 @@ use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain}; use crate::{ device::Device, - hal_api::HalApi, init_tracker::*, resource::{DestroyedResourceError, ParentDevice, Texture, Trackable}, snatch::SnatchGuard, @@ -15,39 +14,31 @@ use super::{clear::clear_texture, BakedCommands, ClearError}; /// Surface that was discarded by `StoreOp::Discard` of a preceding renderpass. /// Any read access to this surface needs to be preceded by a texture initialization. #[derive(Clone)] -pub(crate) struct TextureSurfaceDiscard { - pub texture: Arc>, +pub(crate) struct TextureSurfaceDiscard { + pub texture: Arc, pub mip_level: u32, pub layer: u32, } -pub(crate) type SurfacesInDiscardState = Vec>; +pub(crate) type SurfacesInDiscardState = Vec; -pub(crate) struct CommandBufferTextureMemoryActions { +#[derive(Default)] +pub(crate) struct CommandBufferTextureMemoryActions { /// The tracker actions that we need to be executed before the command /// buffer is executed. - init_actions: Vec>, + init_actions: Vec, /// All the discards that haven't been followed by init again within the /// command buffer i.e. everything in this list resets the texture init /// state *after* the command buffer execution - discards: Vec>, + discards: Vec, } -impl Default for CommandBufferTextureMemoryActions { - fn default() -> Self { - Self { - init_actions: Default::default(), - discards: Default::default(), - } - } -} - -impl CommandBufferTextureMemoryActions { - pub(crate) fn drain_init_actions(&mut self) -> Drain> { +impl CommandBufferTextureMemoryActions { + pub(crate) fn drain_init_actions(&mut self) -> Drain { self.init_actions.drain(..) } - pub(crate) fn discard(&mut self, discard: TextureSurfaceDiscard) { + pub(crate) fn discard(&mut self, discard: TextureSurfaceDiscard) { self.discards.push(discard); } @@ -57,8 +48,8 @@ impl CommandBufferTextureMemoryActions { #[must_use] pub(crate) fn register_init_action( &mut self, - action: &TextureInitTrackerAction, - ) -> SurfacesInDiscardState { + action: &TextureInitTrackerAction, + ) -> SurfacesInDiscardState { let mut immediately_necessary_clears = SurfacesInDiscardState::new(); // Note that within a command buffer we may stack arbitrary memory init @@ -117,7 +108,7 @@ impl CommandBufferTextureMemoryActions { // implicit init, not requiring any immediate resource init. pub(crate) fn register_implicit_init( &mut self, - texture: &Arc>, + texture: &Arc, range: TextureInitRange, ) { let must_be_empty = self.register_init_action(&TextureInitTrackerAction { @@ -133,14 +124,11 @@ impl CommandBufferTextureMemoryActions { // register_init_action and initializes them on the spot. // // Takes care of barriers as well! -pub(crate) fn fixup_discarded_surfaces< - A: HalApi, - InitIter: Iterator>, ->( +pub(crate) fn fixup_discarded_surfaces>( inits: InitIter, encoder: &mut dyn hal::DynCommandEncoder, - texture_tracker: &mut TextureTracker, - device: &Device, + texture_tracker: &mut TextureTracker, + device: &Device, snatch_guard: &SnatchGuard<'_>, ) { for init in inits { @@ -160,12 +148,12 @@ pub(crate) fn fixup_discarded_surfaces< } } -impl BakedCommands { +impl BakedCommands { // inserts all buffer initializations that are going to be needed for // executing the commands and updates resource init states accordingly pub(crate) fn initialize_buffer_memory( &mut self, - device_tracker: &mut DeviceTracker, + device_tracker: &mut DeviceTracker, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), DestroyedResourceError> { profiling::scope!("initialize_buffer_memory"); @@ -265,8 +253,8 @@ impl BakedCommands { // uninitialized pub(crate) fn initialize_texture_memory( &mut self, - device_tracker: &mut DeviceTracker, - device: &Device, + device_tracker: &mut DeviceTracker, + device: &Device, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), DestroyedResourceError> { profiling::scope!("initialize_texture_memory"); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index df9360e775..d2714087df 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -37,7 +37,7 @@ use crate::init_tracker::BufferInitTrackerAction; use crate::resource::Labeled; use crate::track::{DeviceTracker, Tracker, UsageScope}; use crate::LabelHelpers; -use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label}; +use crate::{api_log, global::Global, id, resource_log, Label}; use thiserror::Error; @@ -240,16 +240,16 @@ impl CommandEncoder { } } -pub(crate) struct BakedCommands { +pub(crate) struct BakedCommands { pub(crate) encoder: Box, pub(crate) list: Vec>, - pub(crate) trackers: Tracker, - buffer_memory_init_actions: Vec>, - texture_memory_actions: CommandBufferTextureMemoryActions, + pub(crate) trackers: Tracker, + buffer_memory_init_actions: Vec, + texture_memory_actions: CommandBufferTextureMemoryActions, } /// The mutable state of a [`CommandBuffer`]. -pub struct CommandBufferMutable { +pub struct CommandBufferMutable { /// The [`wgpu_hal::Api::CommandBuffer`]s we've built so far, and the encoder /// they belong to. /// @@ -260,7 +260,7 @@ pub struct CommandBufferMutable { status: CommandEncoderStatus, /// All the resources that the commands recorded so far have referred to. - pub(crate) trackers: Tracker, + pub(crate) trackers: Tracker, /// The regions of buffers and textures these commands will read and write. /// @@ -268,18 +268,18 @@ pub struct CommandBufferMutable { /// buffers/textures we actually need to initialize. If we're /// definitely going to write to something before we read from it, /// we don't need to clear its contents. - buffer_memory_init_actions: Vec>, - texture_memory_actions: CommandBufferTextureMemoryActions, + buffer_memory_init_actions: Vec, + texture_memory_actions: CommandBufferTextureMemoryActions, - pub(crate) pending_query_resets: QueryResetMap, + pub(crate) pending_query_resets: QueryResetMap, #[cfg(feature = "trace")] pub(crate) commands: Option>, } -impl CommandBufferMutable { +impl CommandBufferMutable { pub(crate) fn open_encoder_and_tracker( &mut self, - ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { + ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { let encoder = self.encoder.open()?; let tracker = &mut self.trackers; @@ -305,8 +305,8 @@ impl CommandBufferMutable { /// - Once a command buffer is submitted to the queue, it is removed from the id /// registry, and its contents are taken to construct a [`BakedCommands`], /// whose contents eventually become the property of the submission queue. -pub struct CommandBuffer { - pub(crate) device: Arc>, +pub struct CommandBuffer { + pub(crate) device: Arc, support_clear_texture: bool, /// The `label` from the descriptor used to create the resource. label: String, @@ -317,10 +317,10 @@ pub struct CommandBuffer { /// When this is submitted, dropped, or destroyed, its contents are /// extracted into a [`BakedCommands`] by /// [`CommandBuffer::extract_baked_commands`]. - pub(crate) data: Mutex>>, + pub(crate) data: Mutex>, } -impl Drop for CommandBuffer { +impl Drop for CommandBuffer { fn drop(&mut self) { resource_log!("Drop {}", self.error_ident()); if self.data.lock().is_none() { @@ -336,10 +336,10 @@ impl Drop for CommandBuffer { } } -impl CommandBuffer { +impl CommandBuffer { pub(crate) fn new( encoder: Box, - device: &Arc>, + device: &Arc, label: &Label, ) -> Self { CommandBuffer { @@ -373,8 +373,8 @@ impl CommandBuffer { pub(crate) fn insert_barriers_from_tracker( raw: &mut dyn hal::DynCommandEncoder, - base: &mut Tracker, - head: &Tracker, + base: &mut Tracker, + head: &Tracker, snatch_guard: &SnatchGuard, ) { profiling::scope!("insert_barriers"); @@ -387,8 +387,8 @@ impl CommandBuffer { pub(crate) fn insert_barriers_from_scope( raw: &mut dyn hal::DynCommandEncoder, - base: &mut Tracker, - head: &UsageScope, + base: &mut Tracker, + head: &UsageScope, snatch_guard: &SnatchGuard, ) { profiling::scope!("insert_barriers"); @@ -401,7 +401,7 @@ impl CommandBuffer { pub(crate) fn drain_barriers( raw: &mut dyn hal::DynCommandEncoder, - base: &mut Tracker, + base: &mut Tracker, snatch_guard: &SnatchGuard, ) { profiling::scope!("drain_barriers"); @@ -425,8 +425,8 @@ impl CommandBuffer { pub(crate) fn insert_barriers_from_device_tracker( raw: &mut dyn hal::DynCommandEncoder, - base: &mut DeviceTracker, - head: &Tracker, + base: &mut DeviceTracker, + head: &Tracker, snatch_guard: &SnatchGuard, ) { profiling::scope!("insert_barriers_from_device_tracker"); @@ -448,7 +448,7 @@ impl CommandBuffer { } } -impl CommandBuffer { +impl CommandBuffer { fn lock_encoder_impl(&self, lock: bool) -> Result<(), CommandEncoderError> { let mut cmd_buf_data_guard = self.data.lock(); let cmd_buf_data = cmd_buf_data_guard.as_mut().unwrap(); @@ -508,7 +508,7 @@ impl CommandBuffer { } } - pub(crate) fn extract_baked_commands(&mut self) -> BakedCommands { + pub(crate) fn extract_baked_commands(&mut self) -> BakedCommands { let data = self.data.lock().take().unwrap(); BakedCommands { encoder: data.encoder.raw, @@ -519,17 +519,17 @@ impl CommandBuffer { } } - pub(crate) fn from_arc_into_baked(self: Arc) -> BakedCommands { + pub(crate) fn from_arc_into_baked(self: Arc) -> BakedCommands { let mut command_buffer = Arc::into_inner(self) .expect("CommandBuffer cannot be destroyed because is still in use"); command_buffer.extract_baked_commands() } } -crate::impl_resource_type_generic!(CommandBuffer); +crate::impl_resource_type!(CommandBuffer); crate::impl_labeled!(CommandBuffer); crate::impl_parent_device!(CommandBuffer); -crate::impl_storage_item_generic!(CommandBuffer); +crate::impl_storage_item!(CommandBuffer); /// A stream of commands for a render pass or compute pass. /// @@ -609,14 +609,14 @@ pub enum CommandEncoderError { } impl Global { - pub fn command_encoder_finish( + pub fn command_encoder_finish( &self, encoder_id: id::CommandEncoderId, _desc: &wgt::CommandBufferDescriptor { +impl QueryResetMap { pub fn new() -> Self { Self { map: FastHashMap::default(), } } - pub fn use_query_set(&mut self, query_set: &Arc>, query: u32) -> bool { + pub fn use_query_set(&mut self, query_set: &Arc, query: u32) -> bool { let vec_pair = self .map .entry(query_set.tracker_index()) @@ -161,12 +160,12 @@ pub enum ResolveError { }, } -impl QuerySet { +impl QuerySet { fn validate_query( self: &Arc, query_type: SimplifiedQueryType, query_index: u32, - reset_state: Option<&mut QueryResetMap>, + reset_state: Option<&mut QueryResetMap>, ) -> Result<(), QueryUseError> { // We need to defer our resets because we are in a renderpass, // add the usage to the reset map. @@ -199,7 +198,7 @@ impl QuerySet { self: &Arc, raw_encoder: &mut dyn hal::DynCommandEncoder, query_index: u32, - reset_state: Option<&mut QueryResetMap>, + reset_state: Option<&mut QueryResetMap>, ) -> Result<(), QueryUseError> { let needs_reset = reset_state.is_none(); self.validate_query(SimplifiedQueryType::Timestamp, query_index, reset_state)?; @@ -216,13 +215,13 @@ impl QuerySet { } } -pub(super) fn validate_and_begin_occlusion_query( - query_set: Arc>, +pub(super) fn validate_and_begin_occlusion_query( + query_set: Arc, raw_encoder: &mut dyn hal::DynCommandEncoder, - tracker: &mut StatelessTracker>, + tracker: &mut StatelessTracker, query_index: u32, - reset_state: Option<&mut QueryResetMap>, - active_query: &mut Option<(Arc>, u32)>, + reset_state: Option<&mut QueryResetMap>, + active_query: &mut Option<(Arc, u32)>, ) -> Result<(), QueryUseError> { let needs_reset = reset_state.is_none(); query_set.validate_query(SimplifiedQueryType::Occlusion, query_index, reset_state)?; @@ -248,9 +247,9 @@ pub(super) fn validate_and_begin_occlusion_query( Ok(()) } -pub(super) fn end_occlusion_query( +pub(super) fn end_occlusion_query( raw_encoder: &mut dyn hal::DynCommandEncoder, - active_query: &mut Option<(Arc>, u32)>, + active_query: &mut Option<(Arc, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { unsafe { raw_encoder.end_query(query_set.raw(), query_index) }; @@ -260,14 +259,14 @@ pub(super) fn end_occlusion_query( } } -pub(super) fn validate_and_begin_pipeline_statistics_query( - query_set: Arc>, +pub(super) fn validate_and_begin_pipeline_statistics_query( + query_set: Arc, raw_encoder: &mut dyn hal::DynCommandEncoder, - tracker: &mut StatelessTracker>, - cmd_buf: &CommandBuffer, + tracker: &mut StatelessTracker, + cmd_buf: &CommandBuffer, query_index: u32, - reset_state: Option<&mut QueryResetMap>, - active_query: &mut Option<(Arc>, u32)>, + reset_state: Option<&mut QueryResetMap>, + active_query: &mut Option<(Arc, u32)>, ) -> Result<(), QueryUseError> { query_set.same_device_as(cmd_buf)?; @@ -299,9 +298,9 @@ pub(super) fn validate_and_begin_pipeline_statistics_query( Ok(()) } -pub(super) fn end_pipeline_statistics_query( +pub(super) fn end_pipeline_statistics_query( raw_encoder: &mut dyn hal::DynCommandEncoder, - active_query: &mut Option<(Arc>, u32)>, + active_query: &mut Option<(Arc, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { unsafe { raw_encoder.end_query(query_set.raw(), query_index) }; @@ -312,13 +311,13 @@ pub(super) fn end_pipeline_statistics_query( } impl Global { - pub fn command_encoder_write_timestamp( + pub fn command_encoder_write_timestamp( &self, command_encoder_id: id::CommandEncoderId, query_set_id: id::QuerySetId, query_index: u32, ) -> Result<(), QueryError> { - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -361,7 +360,7 @@ impl Global { Ok(()) } - pub fn command_encoder_resolve_query_set( + pub fn command_encoder_resolve_query_set( &self, command_encoder_id: id::CommandEncoderId, query_set_id: id::QuerySetId, @@ -370,7 +369,7 @@ impl Global { destination: id::BufferId, destination_offset: BufferAddress, ) -> Result<(), QueryError> { - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 7e7f9a1af8..1128e60a54 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -21,7 +21,6 @@ use crate::{ RenderPassCompatibilityError, RenderPassContext, }, global::Global, - hal_api::HalApi, hal_label, id, init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction}, pipeline::{self, PipelineFlags}, @@ -133,11 +132,11 @@ pub struct RenderPassColorAttachment { /// Describes a color attachment to a render pass. #[derive(Debug)] -struct ArcRenderPassColorAttachment { +struct ArcRenderPassColorAttachment { /// The view to use as an attachment. - pub view: Arc>, + pub view: Arc, /// The view that will receive the resolved output if multisampling is used. - pub resolve_target: Option>>, + pub resolve_target: Option>, /// What operations will be performed on this color attachment. pub channel: PassChannel, } @@ -156,16 +155,16 @@ pub struct RenderPassDepthStencilAttachment { } /// Describes a depth/stencil attachment to a render pass. #[derive(Debug)] -pub struct ArcRenderPassDepthStencilAttachment { +pub struct ArcRenderPassDepthStencilAttachment { /// The view to use as an attachment. - pub view: Arc>, + pub view: Arc, /// What operations will be performed on the depth part of the attachment. pub depth: PassChannel, /// What operations will be performed on the stencil part of the attachment. pub stencil: PassChannel, } -impl ArcRenderPassDepthStencilAttachment { +impl ArcRenderPassDepthStencilAttachment { /// Validate the given aspects' read-only flags against their load /// and store ops. /// @@ -218,45 +217,45 @@ pub struct RenderPassDescriptor<'a> { } /// Describes the attachments of a render pass. -struct ArcRenderPassDescriptor<'a, A: HalApi> { +struct ArcRenderPassDescriptor<'a> { pub label: &'a Label<'a>, /// The color attachments of the render pass. pub color_attachments: - ArrayVec>, { hal::MAX_COLOR_ATTACHMENTS }>, + ArrayVec, { hal::MAX_COLOR_ATTACHMENTS }>, /// The depth and stencil attachment of the render pass, if any. - pub depth_stencil_attachment: Option>, + pub depth_stencil_attachment: Option, /// Defines where and when timestamp values will be written for this pass. - pub timestamp_writes: Option>, + pub timestamp_writes: Option, /// Defines where the occlusion query results will be stored for this pass. - pub occlusion_query_set: Option>>, + pub occlusion_query_set: Option>, } -pub struct RenderPass { +pub struct RenderPass { /// All pass data & records is stored here. /// /// If this is `None`, the pass is in the 'ended' state and can no longer be used. /// Any attempt to record more commands will result in a validation error. - base: Option>>, + base: Option>, /// Parent command buffer that this pass records commands into. /// /// If it is none, this pass is invalid and any operation on it will return an error. - parent: Option>>, + parent: Option>, color_attachments: - ArrayVec>, { hal::MAX_COLOR_ATTACHMENTS }>, - depth_stencil_attachment: Option>, - timestamp_writes: Option>, - occlusion_query_set: Option>>, + ArrayVec, { hal::MAX_COLOR_ATTACHMENTS }>, + depth_stencil_attachment: Option, + timestamp_writes: Option, + occlusion_query_set: Option>, // Resource binding dedupe state. current_bind_groups: BindGroupStateChange, current_pipeline: StateChange, } -impl RenderPass { +impl RenderPass { /// If the parent command buffer is invalid, the returned pass will be invalid. - fn new(parent: Option>>, desc: ArcRenderPassDescriptor) -> Self { + fn new(parent: Option>, desc: ArcRenderPassDescriptor) -> Self { let ArcRenderPassDescriptor { label, timestamp_writes, @@ -286,7 +285,7 @@ impl RenderPass { fn base_mut<'a>( &'a mut self, scope: PassErrorScope, - ) -> Result<&'a mut BasePass>, RenderPassError> { + ) -> Result<&'a mut BasePass, RenderPassError> { self.base .as_mut() .ok_or(RenderPassErrorInner::PassEnded) @@ -294,7 +293,7 @@ impl RenderPass { } } -impl fmt::Debug for RenderPass { +impl fmt::Debug for RenderPass { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RenderPass") .field("label", &self.label()) @@ -444,38 +443,38 @@ impl VertexState { } } -struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { +struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> { pipeline_flags: PipelineFlags, - binder: Binder, + binder: Binder, blend_constant: OptionalState, stencil_reference: u32, - pipeline: Option>>, + pipeline: Option>, index: IndexState, vertex: VertexState, debug_scope_depth: u32, - info: RenderPassInfo<'scope, A>, + info: RenderPassInfo<'scope>, snatch_guard: &'snatch_guard SnatchGuard<'snatch_guard>, - device: &'cmd_buf Arc>, + device: &'cmd_buf Arc, raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, - tracker: &'cmd_buf mut Tracker, - buffer_memory_init_actions: &'cmd_buf mut Vec>, - texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions, + tracker: &'cmd_buf mut Tracker, + buffer_memory_init_actions: &'cmd_buf mut Vec, + texture_memory_actions: &'cmd_buf mut CommandBufferTextureMemoryActions, temp_offsets: Vec, dynamic_offset_count: usize, string_offset: usize, - active_occlusion_query: Option<(Arc>, u32)>, - active_pipeline_statistics_query: Option<(Arc>, u32)>, + active_occlusion_query: Option<(Arc, u32)>, + active_pipeline_statistics_query: Option<(Arc, u32)>, } -impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> - State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A> +impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> + State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> { fn is_ready(&self, indexed: bool) -> Result<(), DrawError> { if let Some(pipeline) = self.pipeline.as_ref() { @@ -747,14 +746,14 @@ where } } -struct RenderAttachment { - texture: Arc>, +struct RenderAttachment { + texture: Arc, selector: TextureSelector, usage: hal::TextureUses, } -impl TextureView { - fn to_render_attachment(&self, usage: hal::TextureUses) -> RenderAttachment { +impl TextureView { + fn to_render_attachment(&self, usage: hal::TextureUses) -> RenderAttachment { RenderAttachment { texture: self.parent.clone(), selector: self.selector.clone(), @@ -766,26 +765,26 @@ impl TextureView { const MAX_TOTAL_ATTACHMENTS: usize = hal::MAX_COLOR_ATTACHMENTS + hal::MAX_COLOR_ATTACHMENTS + 1; type AttachmentDataVec = ArrayVec; -struct RenderPassInfo<'d, A: HalApi> { +struct RenderPassInfo<'d> { context: RenderPassContext, - usage_scope: UsageScope<'d, A>, + usage_scope: UsageScope<'d>, /// All render attachments, including depth/stencil - render_attachments: AttachmentDataVec>, + render_attachments: AttachmentDataVec, is_depth_read_only: bool, is_stencil_read_only: bool, extent: wgt::Extent3d, - pending_discard_init_fixups: SurfacesInDiscardState, - divergent_discarded_depth_stencil_aspect: Option<(wgt::TextureAspect, Arc>)>, + pending_discard_init_fixups: SurfacesInDiscardState, + divergent_discarded_depth_stencil_aspect: Option<(wgt::TextureAspect, Arc)>, multiview: Option, } -impl<'d, A: HalApi> RenderPassInfo<'d, A> { +impl<'d> RenderPassInfo<'d> { fn add_pass_texture_init_actions( channel: &PassChannel, - texture_memory_actions: &mut CommandBufferTextureMemoryActions, - view: &TextureView, - pending_discard_init_fixups: &mut SurfacesInDiscardState, + texture_memory_actions: &mut CommandBufferTextureMemoryActions, + view: &TextureView, + pending_discard_init_fixups: &mut SurfacesInDiscardState, ) { if channel.load_op == LoadOp::Load { pending_discard_init_fixups.extend(texture_memory_actions.register_init_action( @@ -816,19 +815,19 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { } fn start( - device: &'d Arc>, + device: &'d Arc, hal_label: Option<&str>, color_attachments: ArrayVec< - Option>, + Option, { hal::MAX_COLOR_ATTACHMENTS }, >, - mut depth_stencil_attachment: Option>, - mut timestamp_writes: Option>, - mut occlusion_query_set: Option>>, + mut depth_stencil_attachment: Option, + mut timestamp_writes: Option, + mut occlusion_query_set: Option>, encoder: &mut CommandEncoder, - trackers: &mut Tracker, - texture_memory_actions: &mut CommandBufferTextureMemoryActions, - pending_query_resets: &mut QueryResetMap, + trackers: &mut Tracker, + texture_memory_actions: &mut CommandBufferTextureMemoryActions, + pending_query_resets: &mut QueryResetMap, snatch_guard: &SnatchGuard<'_>, ) -> Result { profiling::scope!("RenderPassInfo::start"); @@ -839,7 +838,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { let mut is_depth_read_only = false; let mut is_stencil_read_only = false; - let mut render_attachments = AttachmentDataVec::>::new(); + let mut render_attachments = AttachmentDataVec::::new(); let mut discarded_surfaces = AttachmentDataVec::new(); let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); let mut divergent_discarded_depth_stencil_aspect = None; @@ -853,7 +852,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { let mut detected_multiview: Option> = None; - let mut check_multiview = |view: &TextureView| { + let mut check_multiview = |view: &TextureView| { // Get the multiview configuration for this texture view let layers = view.selector.layers.end - view.selector.layers.start; let this_multiview = if layers >= 2 { @@ -884,7 +883,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { Ok(()) }; - let mut add_view = |view: &TextureView, location| { + let mut add_view = |view: &TextureView, location| { let render_extent = view.render_extent.map_err(|reason| { RenderPassErrorInner::TextureViewIsNotRenderable { location, reason } })?; @@ -1048,7 +1047,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { color_attachments_hal.push(None); continue; }; - let color_view: &TextureView = &at.view; + let color_view: &TextureView = &at.view; color_view.same_device(device)?; check_multiview(color_view)?; add_view( @@ -1256,7 +1255,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { mut self, raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, - ) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState), RenderPassErrorInner> { + ) -> Result<(UsageScope<'d>, SurfacesInDiscardState), RenderPassErrorInner> { profiling::scope!("RenderPassInfo::finish"); unsafe { raw.end_render_pass(); @@ -1332,16 +1331,16 @@ impl Global { /// Any operation on an invalid pass will return an error. /// /// If successful, puts the encoder into the [`CommandEncoderStatus::Locked`] state. - pub fn command_encoder_create_render_pass( + pub fn command_encoder_create_render_pass( &self, encoder_id: id::CommandEncoderId, desc: &RenderPassDescriptor<'_>, - ) -> (RenderPass, Option) { - fn fill_arc_desc( - hub: &crate::hub::Hub, + ) -> (RenderPass, Option) { + fn fill_arc_desc( + hub: &crate::hub::Hub, desc: &RenderPassDescriptor<'_>, - arc_desc: &mut ArcRenderPassDescriptor, - device: &Device, + arc_desc: &mut ArcRenderPassDescriptor, + device: &Device, ) -> Result<(), CommandEncoderError> { let query_sets = hub.query_sets.read(); let texture_views = hub.texture_views.read(); @@ -1436,7 +1435,7 @@ impl Global { Ok(()) } - let hub = A::hub(self); + let hub = &self.hub; let mut arc_desc = ArcRenderPassDescriptor { label: &desc.label, timestamp_writes: None, @@ -1466,18 +1465,18 @@ impl Global { /// /// If creation fails, an invalid pass is returned. /// Any operation on an invalid pass will return an error. - pub fn command_encoder_create_render_pass_dyn( + pub fn command_encoder_create_render_pass_dyn( &self, encoder_id: id::CommandEncoderId, desc: &RenderPassDescriptor<'_>, ) -> (Box, Option) { - let (pass, err) = self.command_encoder_create_render_pass::(encoder_id, desc); + let (pass, err) = self.command_encoder_create_render_pass(encoder_id, desc); (Box::new(pass), err) } #[doc(hidden)] #[cfg(any(feature = "serde", feature = "replay"))] - pub fn render_pass_end_with_unresolved_commands( + pub fn render_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, base: BasePass, @@ -1490,7 +1489,7 @@ impl Global { #[cfg(feature = "trace")] { - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub.command_buffers.get(encoder_id.into_command_buffer_id()) { Ok(cmd_buf) => cmd_buf, @@ -1525,7 +1524,7 @@ impl Global { push_constant_data, } = base; - let (mut render_pass, encoder_error) = self.command_encoder_create_render_pass::( + let (mut render_pass, encoder_error) = self.command_encoder_create_render_pass( encoder_id, &RenderPassDescriptor { label: label.as_deref().map(Cow::Borrowed), @@ -1542,7 +1541,7 @@ impl Global { }); }; - let hub = A::hub(self); + let hub = &self.hub; render_pass.base = Some(BasePass { label, commands: super::RenderCommand::resolve_render_command_ids(hub, &commands)?, @@ -1562,10 +1561,7 @@ impl Global { } #[doc(hidden)] - pub fn render_pass_end( - &self, - pass: &mut RenderPass, - ) -> Result<(), RenderPassError> { + pub fn render_pass_end(&self, pass: &mut RenderPass) -> Result<(), RenderPassError> { let pass_scope = PassErrorScope::Pass; let base = pass @@ -1945,13 +1941,13 @@ impl Global { } } -fn set_bind_group( - state: &mut State, - cmd_buf: &Arc>, +fn set_bind_group( + state: &mut State, + cmd_buf: &Arc, dynamic_offsets: &[DynamicOffset], index: u32, num_dynamic_offsets: usize, - bind_group: Arc>, + bind_group: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!( "RenderPass::set_bind_group {index} {}", @@ -2026,10 +2022,10 @@ fn set_bind_group( Ok(()) } -fn set_pipeline( - state: &mut State, - cmd_buf: &Arc>, - pipeline: Arc>, +fn set_pipeline( + state: &mut State, + cmd_buf: &Arc, + pipeline: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_pipeline {}", pipeline.error_ident()); @@ -2135,10 +2131,10 @@ fn set_pipeline( Ok(()) } -fn set_index_buffer( - state: &mut State, - cmd_buf: &Arc>, - buffer: Arc>, +fn set_index_buffer( + state: &mut State, + cmd_buf: &Arc, + buffer: Arc, index_format: IndexFormat, offset: u64, size: Option, @@ -2181,11 +2177,11 @@ fn set_index_buffer( Ok(()) } -fn set_vertex_buffer( - state: &mut State, - cmd_buf: &Arc>, +fn set_vertex_buffer( + state: &mut State, + cmd_buf: &Arc, slot: u32, - buffer: Arc>, + buffer: Arc, offset: u64, size: Option, ) -> Result<(), RenderPassErrorInner> { @@ -2247,7 +2243,7 @@ fn set_vertex_buffer( Ok(()) } -fn set_blend_constant(state: &mut State, color: &Color) { +fn set_blend_constant(state: &mut State, color: &Color) { api_log!("RenderPass::set_blend_constant"); state.blend_constant = OptionalState::Set; @@ -2262,7 +2258,7 @@ fn set_blend_constant(state: &mut State, color: &Color) { } } -fn set_stencil_reference(state: &mut State, value: u32) { +fn set_stencil_reference(state: &mut State, value: u32) { api_log!("RenderPass::set_stencil_reference {value}"); state.stencil_reference = value; @@ -2276,8 +2272,8 @@ fn set_stencil_reference(state: &mut State, value: u32) { } } -fn set_viewport( - state: &mut State, +fn set_viewport( + state: &mut State, rect: Rect, depth_min: f32, depth_max: f32, @@ -2307,8 +2303,8 @@ fn set_viewport( Ok(()) } -fn set_push_constant( - state: &mut State, +fn set_push_constant( + state: &mut State, push_constant_data: &[u32], stages: ShaderStages, offset: u32, @@ -2341,10 +2337,7 @@ fn set_push_constant( Ok(()) } -fn set_scissor( - state: &mut State, - rect: Rect, -) -> Result<(), RenderPassErrorInner> { +fn set_scissor(state: &mut State, rect: Rect) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_scissor_rect {rect:?}"); if rect.x + rect.w > state.info.extent.width || rect.y + rect.h > state.info.extent.height { @@ -2362,8 +2355,8 @@ fn set_scissor( Ok(()) } -fn draw( - state: &mut State, +fn draw( + state: &mut State, vertex_count: u32, instance_count: u32, first_vertex: u32, @@ -2402,8 +2395,8 @@ fn draw( Ok(()) } -fn draw_indexed( - state: &mut State, +fn draw_indexed( + state: &mut State, index_count: u32, instance_count: u32, first_index: u32, @@ -2446,10 +2439,10 @@ fn draw_indexed( Ok(()) } -fn multi_draw_indirect( - state: &mut State, - cmd_buf: &Arc>, - indirect_buffer: Arc>, +fn multi_draw_indirect( + state: &mut State, + cmd_buf: &Arc, + indirect_buffer: Arc, offset: u64, count: Option, indexed: bool, @@ -2521,12 +2514,12 @@ fn multi_draw_indirect( Ok(()) } -fn multi_draw_indirect_count( - state: &mut State, - cmd_buf: &Arc>, - indirect_buffer: Arc>, +fn multi_draw_indirect_count( + state: &mut State, + cmd_buf: &Arc, + indirect_buffer: Arc, offset: u64, - count_buffer: Arc>, + count_buffer: Arc, count_buffer_offset: u64, max_count: u32, indexed: bool, @@ -2629,7 +2622,7 @@ fn multi_draw_indirect_count( Ok(()) } -fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) { +fn push_debug_group(state: &mut State, string_data: &[u8], len: usize) { state.debug_scope_depth += 1; if !state .device @@ -2647,7 +2640,7 @@ fn push_debug_group(state: &mut State, string_data: &[u8], len: us state.string_offset += len; } -fn pop_debug_group(state: &mut State) -> Result<(), RenderPassErrorInner> { +fn pop_debug_group(state: &mut State) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::pop_debug_group"); if state.debug_scope_depth == 0 { @@ -2666,7 +2659,7 @@ fn pop_debug_group(state: &mut State) -> Result<(), RenderPassErro Ok(()) } -fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) { +fn insert_debug_marker(state: &mut State, string_data: &[u8], len: usize) { if !state .device .instance_flags @@ -2682,11 +2675,11 @@ fn insert_debug_marker(state: &mut State, string_data: &[u8], len: state.string_offset += len; } -fn write_timestamp( - state: &mut State, - cmd_buf: &CommandBuffer, - pending_query_resets: &mut QueryResetMap, - query_set: Arc>, +fn write_timestamp( + state: &mut State, + cmd_buf: &CommandBuffer, + pending_query_resets: &mut QueryResetMap, + query_set: Arc, query_index: u32, ) -> Result<(), RenderPassErrorInner> { api_log!( @@ -2710,10 +2703,10 @@ fn write_timestamp( Ok(()) } -fn execute_bundle( - state: &mut State, - cmd_buf: &Arc>, - bundle: Arc>, +fn execute_bundle( + state: &mut State, + cmd_buf: &Arc, + bundle: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::execute_bundle {}", bundle.error_ident()); @@ -2774,12 +2767,12 @@ fn execute_bundle( } impl Global { - fn resolve_render_pass_buffer_id( + fn resolve_render_pass_buffer_id( &self, scope: PassErrorScope, buffer_id: id::Id, - ) -> Result>, RenderPassError> { - let hub = A::hub(self); + ) -> Result, RenderPassError> { + let hub = &self.hub; let buffer = hub .buffers .get(buffer_id) @@ -2789,12 +2782,12 @@ impl Global { Ok(buffer) } - fn resolve_render_pass_query_set( + fn resolve_render_pass_query_set( &self, scope: PassErrorScope, query_set_id: id::Id, - ) -> Result>, RenderPassError> { - let hub = A::hub(self); + ) -> Result, RenderPassError> { + let hub = &self.hub; let query_set = hub .query_sets .get(query_set_id) @@ -2804,9 +2797,9 @@ impl Global { Ok(query_set) } - pub fn render_pass_set_bind_group( + pub fn render_pass_set_bind_group( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, index: u32, bind_group_id: id::BindGroupId, offsets: &[DynamicOffset], @@ -2828,7 +2821,7 @@ impl Global { return Ok(()); } - let hub = A::hub(self); + let hub = &self.hub; let bind_group = hub .bind_groups .get(bind_group_id) @@ -2844,9 +2837,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_pipeline( + pub fn render_pass_set_pipeline( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, pipeline_id: id::RenderPipelineId, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::SetPipelineRender; @@ -2859,7 +2852,7 @@ impl Global { return Ok(()); } - let hub = A::hub(self); + let hub = &self.hub; let pipeline = hub .render_pipelines .get(pipeline_id) @@ -2871,9 +2864,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_index_buffer( + pub fn render_pass_set_index_buffer( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, index_format: IndexFormat, offset: BufferAddress, @@ -2892,9 +2885,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_vertex_buffer( + pub fn render_pass_set_vertex_buffer( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, slot: u32, buffer_id: id::BufferId, offset: BufferAddress, @@ -2913,9 +2906,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_blend_constant( + pub fn render_pass_set_blend_constant( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, color: Color, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::SetBlendConstant; @@ -2927,9 +2920,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_stencil_reference( + pub fn render_pass_set_stencil_reference( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, value: u32, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::SetStencilReference; @@ -2941,9 +2934,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_viewport( + pub fn render_pass_set_viewport( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, x: f32, y: f32, w: f32, @@ -2963,9 +2956,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_scissor_rect( + pub fn render_pass_set_scissor_rect( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, x: u32, y: u32, w: u32, @@ -2980,9 +2973,9 @@ impl Global { Ok(()) } - pub fn render_pass_set_push_constants( + pub fn render_pass_set_push_constants( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, stages: ShaderStages, offset: u32, data: &[u8], @@ -3019,9 +3012,9 @@ impl Global { Ok(()) } - pub fn render_pass_draw( + pub fn render_pass_draw( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, vertex_count: u32, instance_count: u32, first_vertex: u32, @@ -3043,9 +3036,9 @@ impl Global { Ok(()) } - pub fn render_pass_draw_indexed( + pub fn render_pass_draw_indexed( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, index_count: u32, instance_count: u32, first_index: u32, @@ -3069,9 +3062,9 @@ impl Global { Ok(()) } - pub fn render_pass_draw_indirect( + pub fn render_pass_draw_indirect( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, ) -> Result<(), RenderPassError> { @@ -3091,9 +3084,9 @@ impl Global { Ok(()) } - pub fn render_pass_draw_indexed_indirect( + pub fn render_pass_draw_indexed_indirect( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, ) -> Result<(), RenderPassError> { @@ -3113,9 +3106,9 @@ impl Global { Ok(()) } - pub fn render_pass_multi_draw_indirect( + pub fn render_pass_multi_draw_indirect( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, count: u32, @@ -3136,9 +3129,9 @@ impl Global { Ok(()) } - pub fn render_pass_multi_draw_indexed_indirect( + pub fn render_pass_multi_draw_indexed_indirect( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, count: u32, @@ -3159,9 +3152,9 @@ impl Global { Ok(()) } - pub fn render_pass_multi_draw_indirect_count( + pub fn render_pass_multi_draw_indirect_count( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, count_buffer_id: id::BufferId, @@ -3175,7 +3168,7 @@ impl Global { let base = pass.base_mut(scope)?; // Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice. - let hub = A::hub(self); + let hub = &self.hub; let buffers = hub.buffers.read(); let buffer = buffers .get_owned(buffer_id) @@ -3199,9 +3192,9 @@ impl Global { Ok(()) } - pub fn render_pass_multi_draw_indexed_indirect_count( + pub fn render_pass_multi_draw_indexed_indirect_count( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, buffer_id: id::BufferId, offset: BufferAddress, count_buffer_id: id::BufferId, @@ -3215,7 +3208,7 @@ impl Global { let base = pass.base_mut(scope)?; // Don't use resolve_render_pass_buffer_id here, because we don't want to take the read-lock twice. - let hub = A::hub(self); + let hub = &self.hub; let buffers = hub.buffers.read(); let buffer = buffers .get_owned(buffer_id) @@ -3240,9 +3233,9 @@ impl Global { Ok(()) } - pub fn render_pass_push_debug_group( + pub fn render_pass_push_debug_group( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, label: &str, color: u32, ) -> Result<(), RenderPassError> { @@ -3259,9 +3252,9 @@ impl Global { Ok(()) } - pub fn render_pass_pop_debug_group( + pub fn render_pass_pop_debug_group( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, ) -> Result<(), RenderPassError> { let base = pass.base_mut(PassErrorScope::PopDebugGroup)?; @@ -3270,9 +3263,9 @@ impl Global { Ok(()) } - pub fn render_pass_insert_debug_marker( + pub fn render_pass_insert_debug_marker( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, label: &str, color: u32, ) -> Result<(), RenderPassError> { @@ -3289,9 +3282,9 @@ impl Global { Ok(()) } - pub fn render_pass_write_timestamp( + pub fn render_pass_write_timestamp( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, query_set_id: id::QuerySetId, query_index: u32, ) -> Result<(), RenderPassError> { @@ -3306,9 +3299,9 @@ impl Global { Ok(()) } - pub fn render_pass_begin_occlusion_query( + pub fn render_pass_begin_occlusion_query( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, query_index: u32, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::BeginOcclusionQuery; @@ -3320,9 +3313,9 @@ impl Global { Ok(()) } - pub fn render_pass_end_occlusion_query( + pub fn render_pass_end_occlusion_query( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::EndOcclusionQuery; let base = pass.base_mut(scope)?; @@ -3332,9 +3325,9 @@ impl Global { Ok(()) } - pub fn render_pass_begin_pipeline_statistics_query( + pub fn render_pass_begin_pipeline_statistics_query( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, query_set_id: id::QuerySetId, query_index: u32, ) -> Result<(), RenderPassError> { @@ -3350,9 +3343,9 @@ impl Global { Ok(()) } - pub fn render_pass_end_pipeline_statistics_query( + pub fn render_pass_end_pipeline_statistics_query( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, ) -> Result<(), RenderPassError> { let scope = PassErrorScope::EndPipelineStatisticsQuery; let base = pass.base_mut(scope)?; @@ -3363,15 +3356,15 @@ impl Global { Ok(()) } - pub fn render_pass_execute_bundles( + pub fn render_pass_execute_bundles( &self, - pass: &mut RenderPass, + pass: &mut RenderPass, render_bundle_ids: &[id::RenderBundleId], ) -> Result<(), RenderPassError> { let scope = PassErrorScope::ExecuteBundle; let base = pass.base_mut(scope)?; - let hub = A::hub(self); + let hub = &self.hub; let bundles = hub.render_bundles.read(); for &bundle_id in render_bundle_ids { diff --git a/wgpu-core/src/command/render_command.rs b/wgpu-core/src/command/render_command.rs index 287aa888f1..891ee3cfbc 100644 --- a/wgpu-core/src/command/render_command.rs +++ b/wgpu-core/src/command/render_command.rs @@ -1,6 +1,5 @@ use crate::{ binding_model::BindGroup, - hal_api::HalApi, id, pipeline::RenderPipeline, resource::{Buffer, QuerySet}, @@ -126,10 +125,10 @@ pub enum RenderCommand { impl RenderCommand { /// Resolves all ids in a list of commands into the corresponding resource Arc. #[cfg(any(feature = "serde", feature = "replay"))] - pub fn resolve_render_command_ids( - hub: &crate::hub::Hub, + pub fn resolve_render_command_ids( + hub: &crate::hub::Hub, commands: &[RenderCommand], - ) -> Result>, super::RenderPassError> { + ) -> Result, super::RenderPassError> { use super::{ DrawKind, PassErrorScope, RenderCommandError, RenderPassError, RenderPassErrorInner, }; @@ -140,9 +139,9 @@ impl RenderCommand { let pipelines_guard = hub.render_pipelines.read(); let render_bundles_guard = hub.render_bundles.read(); - let resolved_commands: Vec> = commands + let resolved_commands: Vec = commands .iter() - .map(|c| -> Result, RenderPassError> { + .map(|c| -> Result { Ok(match *c { RenderCommand::SetBindGroup { index, @@ -381,22 +380,22 @@ impl RenderCommand { /// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs. #[doc(hidden)] #[derive(Clone, Debug)] -pub enum ArcRenderCommand { +pub enum ArcRenderCommand { SetBindGroup { index: u32, num_dynamic_offsets: usize, - bind_group: Arc>, + bind_group: Arc, }, - SetPipeline(Arc>), + SetPipeline(Arc), SetIndexBuffer { - buffer: Arc>, + buffer: Arc, index_format: wgt::IndexFormat, offset: BufferAddress, size: Option, }, SetVertexBuffer { slot: u32, - buffer: Arc>, + buffer: Arc, offset: BufferAddress, size: Option, }, @@ -450,16 +449,16 @@ pub enum ArcRenderCommand { first_instance: u32, }, MultiDrawIndirect { - buffer: Arc>, + buffer: Arc, offset: BufferAddress, /// Count of `None` represents a non-multi call. count: Option, indexed: bool, }, MultiDrawIndirectCount { - buffer: Arc>, + buffer: Arc, offset: BufferAddress, - count_buffer: Arc>, + count_buffer: Arc, count_buffer_offset: BufferAddress, max_count: u32, indexed: bool, @@ -474,7 +473,7 @@ pub enum ArcRenderCommand { len: usize, }, WriteTimestamp { - query_set: Arc>, + query_set: Arc, query_index: u32, }, BeginOcclusionQuery { @@ -482,9 +481,9 @@ pub enum ArcRenderCommand { }, EndOcclusionQuery, BeginPipelineStatisticsQuery { - query_set: Arc>, + query_set: Arc, query_index: u32, }, EndPipelineStatisticsQuery, - ExecuteBundle(Arc>), + ExecuteBundle(Arc), } diff --git a/wgpu-core/src/command/timestamp_writes.rs b/wgpu-core/src/command/timestamp_writes.rs index 82ab13c6dd..e91b48534d 100644 --- a/wgpu-core/src/command/timestamp_writes.rs +++ b/wgpu-core/src/command/timestamp_writes.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use crate::{hal_api::HalApi, id}; +use crate::id; /// Describes the writing of timestamp values in a render or compute pass. #[derive(Clone, Debug, PartialEq, Eq)] @@ -15,9 +15,9 @@ pub struct PassTimestampWrites { } /// Describes the writing of timestamp values in a render or compute pass with the query set resolved. -pub struct ArcPassTimestampWrites { +pub struct ArcPassTimestampWrites { /// The query set to write the timestamps to. - pub query_set: Arc>, + pub query_set: Arc, /// The index of the query set at which a start timestamp of this pass is written, if any. pub beginning_of_pass_write_index: Option, /// The index of the query set at which an end timestamp of this pass is written, if any. diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 4ccc762720..de5ef9ed84 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -6,7 +6,6 @@ use crate::{ conv, device::{Device, DeviceError, MissingDownlevelFlags}, global::Global, - hal_api::HalApi, id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, @@ -159,10 +158,10 @@ impl From for CopyError { } } -pub(crate) fn extract_texture_selector( +pub(crate) fn extract_texture_selector( copy_texture: &ImageCopyTexture, copy_size: &Extent3d, - texture: &Texture, + texture: &Texture, ) -> Result<(TextureSelector, hal::TextureCopyBase), TransferError> { let format = texture.desc.format; let copy_aspect = hal::FormatAspects::new(format, copy_texture.aspect); @@ -407,15 +406,15 @@ pub(crate) fn validate_texture_copy_range( Ok((copy_extent, array_layer_count)) } -fn handle_texture_init( +fn handle_texture_init( init_kind: MemoryInitKind, encoder: &mut CommandEncoder, - trackers: &mut Tracker, - texture_memory_actions: &mut CommandBufferTextureMemoryActions, - device: &Device, + trackers: &mut Tracker, + texture_memory_actions: &mut CommandBufferTextureMemoryActions, + device: &Device, copy_texture: &ImageCopyTexture, copy_size: &Extent3d, - texture: &Arc>, + texture: &Arc, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), ClearError> { let init_action = TextureInitTrackerAction { @@ -457,14 +456,14 @@ fn handle_texture_init( /// /// Ensure the source texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. -fn handle_src_texture_init( +fn handle_src_texture_init( encoder: &mut CommandEncoder, - trackers: &mut Tracker, - texture_memory_actions: &mut CommandBufferTextureMemoryActions, - device: &Device, + trackers: &mut Tracker, + texture_memory_actions: &mut CommandBufferTextureMemoryActions, + device: &Device, source: &ImageCopyTexture, copy_size: &Extent3d, - texture: &Arc>, + texture: &Arc, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { handle_texture_init( @@ -485,14 +484,14 @@ fn handle_src_texture_init( /// /// Ensure the destination texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. -fn handle_dst_texture_init( +fn handle_dst_texture_init( encoder: &mut CommandEncoder, - trackers: &mut Tracker, - texture_memory_actions: &mut CommandBufferTextureMemoryActions, - device: &Device, + trackers: &mut Tracker, + texture_memory_actions: &mut CommandBufferTextureMemoryActions, + device: &Device, destination: &ImageCopyTexture, copy_size: &Extent3d, - texture: &Arc>, + texture: &Arc, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { // Attention: If we don't write full texture subresources, we need to a full @@ -524,7 +523,7 @@ fn handle_dst_texture_init( } impl Global { - pub fn command_encoder_copy_buffer_to_buffer( + pub fn command_encoder_copy_buffer_to_buffer( &self, command_encoder_id: CommandEncoderId, source: BufferId, @@ -541,7 +540,7 @@ impl Global { if source == destination { return Err(TransferError::SameSourceDestinationBuffer.into()); } - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -697,7 +696,7 @@ impl Global { Ok(()) } - pub fn command_encoder_copy_buffer_to_texture( + pub fn command_encoder_copy_buffer_to_texture( &self, command_encoder_id: CommandEncoderId, source: &ImageCopyBuffer, @@ -711,7 +710,7 @@ impl Global { destination.texture ); - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -865,7 +864,7 @@ impl Global { Ok(()) } - pub fn command_encoder_copy_texture_to_buffer( + pub fn command_encoder_copy_texture_to_buffer( &self, command_encoder_id: CommandEncoderId, source: &ImageCopyTexture, @@ -879,7 +878,7 @@ impl Global { destination.buffer ); - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers @@ -1045,7 +1044,7 @@ impl Global { Ok(()) } - pub fn command_encoder_copy_texture_to_texture( + pub fn command_encoder_copy_texture_to_texture( &self, command_encoder_id: CommandEncoderId, source: &ImageCopyTexture, @@ -1059,7 +1058,7 @@ impl Global { destination.texture ); - let hub = A::hub(self); + let hub = &self.hub; let cmd_buf = match hub .command_buffers diff --git a/wgpu-core/src/device/any_device.rs b/wgpu-core/src/device/any_device.rs deleted file mode 100644 index e796bf0574..0000000000 --- a/wgpu-core/src/device/any_device.rs +++ /dev/null @@ -1,102 +0,0 @@ -use wgt::Backend; - -use super::Device; -/// The `AnyDevice` type: a pointer to a `Device` for any backend `A`. -use crate::hal_api::HalApi; - -use std::fmt; -use std::mem::ManuallyDrop; -use std::ptr::NonNull; -use std::sync::Arc; - -struct AnyDeviceVtable { - // We oppurtunistically store the backend here, since we now it will be used - // with backend selection and it can be stored in static memory. - backend: Backend, - // Drop glue which knows how to drop the stored data. - drop: unsafe fn(*mut ()), -} - -/// A pointer to a `Device`, for any backend `A`. -/// -/// Any `AnyDevice` is just like an `Arc>`, except that the `A` type -/// parameter is erased. To access the `Device`, you must downcast to a -/// particular backend with the \[`downcast_ref`\] or \[`downcast_clone`\] -/// methods. -pub struct AnyDevice { - data: NonNull<()>, - vtable: &'static AnyDeviceVtable, -} - -impl AnyDevice { - /// Return an `AnyDevice` that holds an owning `Arc` pointer to `device`. - pub fn new(device: Arc>) -> AnyDevice { - unsafe fn drop_glue(ptr: *mut ()) { - // Drop the arc this instance is holding. - unsafe { - _ = Arc::from_raw(ptr.cast::>()); - } - } - - // SAFETY: The pointer returned by Arc::into_raw is guaranteed to be - // non-null. - let data = unsafe { NonNull::new_unchecked(Arc::into_raw(device).cast_mut()) }; - - AnyDevice { - data: data.cast(), - vtable: &AnyDeviceVtable { - backend: A::VARIANT, - drop: drop_glue::, - }, - } - } - - /// If `self` is an `Arc>`, return a reference to the - /// device. - pub fn downcast_ref(&self) -> Option<&Device> { - if self.vtable.backend != A::VARIANT { - return None; - } - - // SAFETY: We just checked the instance above implicitly by the backend - // that it was statically constructed through. - Some(unsafe { &*(self.data.as_ptr().cast::>()) }) - } - - /// If `self` is an `Arc>`, return a clone of that. - pub fn downcast_clone(&self) -> Option>> { - if self.vtable.backend != A::VARIANT { - return None; - } - - // We need to prevent the destructor of the arc from running, since it - // refers to the instance held by this object. Dropping it would - // invalidate this object. - // - // SAFETY: We just checked the instance above implicitly by the backend - // that it was statically constructed through. - let this = - ManuallyDrop::new(unsafe { Arc::from_raw(self.data.as_ptr().cast::>()) }); - - // Cloning it increases the reference count, and we return a new arc - // instance. - Some((*this).clone()) - } -} - -impl Drop for AnyDevice { - fn drop(&mut self) { - unsafe { (self.vtable.drop)(self.data.as_ptr()) } - } -} - -impl fmt::Debug for AnyDevice { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "AnyDevice<{}>", self.vtable.backend) - } -} - -#[cfg(send_sync)] -unsafe impl Send for AnyDevice {} -#[cfg(send_sync)] -unsafe impl Sync for AnyDevice {} diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index f456a00ca2..d9f983d1a8 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -31,12 +31,12 @@ use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering}; use super::{ImplicitPipelineIds, UserClosures}; impl Global { - pub fn adapter_is_surface_supported( + pub fn adapter_is_surface_supported( &self, adapter_id: AdapterId, surface_id: SurfaceId, ) -> Result { - let hub = A::hub(self); + let hub = &self.hub; let surface_guard = self.surfaces.read(); let adapter_guard = hub.adapters.read(); @@ -49,13 +49,13 @@ impl Global { Ok(adapter.is_surface_supported(surface)) } - pub fn surface_get_capabilities( + pub fn surface_get_capabilities( &self, surface_id: SurfaceId, adapter_id: AdapterId, ) -> Result { profiling::scope!("Surface::get_capabilities"); - self.fetch_adapter_and_surface::(surface_id, adapter_id, |adapter, surface| { + self.fetch_adapter_and_surface::<_, _>(surface_id, adapter_id, |adapter, surface| { let mut hal_caps = surface.get_capabilities(adapter)?; hal_caps.formats.sort_by_key(|f| !f.is_srgb()); @@ -72,7 +72,6 @@ impl Global { } fn fetch_adapter_and_surface< - A: HalApi, F: FnOnce(&Adapter, &Surface) -> Result, B, >( @@ -81,7 +80,7 @@ impl Global { adapter_id: AdapterId, get_supported_callback: F, ) -> Result { - let hub = A::hub(self); + let hub = &self.hub; let surface_guard = self.surfaces.read(); let adapter_guard = hub.adapters.read(); @@ -95,11 +94,8 @@ impl Global { get_supported_callback(adapter, surface) } - pub fn device_features( - &self, - device_id: DeviceId, - ) -> Result { - let hub = A::hub(self); + pub fn device_features(&self, device_id: DeviceId) -> Result { + let hub = &self.hub; let device = hub .devices @@ -109,11 +105,8 @@ impl Global { Ok(device.features) } - pub fn device_limits( - &self, - device_id: DeviceId, - ) -> Result { - let hub = A::hub(self); + pub fn device_limits(&self, device_id: DeviceId) -> Result { + let hub = &self.hub; let device = hub .devices @@ -123,11 +116,11 @@ impl Global { Ok(device.limits.clone()) } - pub fn device_downlevel_properties( + pub fn device_downlevel_properties( &self, device_id: DeviceId, ) -> Result { - let hub = A::hub(self); + let hub = &self.hub; let device = hub .devices @@ -137,7 +130,7 @@ impl Global { Ok(device.downlevel.clone()) } - pub fn device_create_buffer( + pub fn device_create_buffer( &self, device_id: DeviceId, desc: &resource::BufferDescriptor, @@ -145,8 +138,8 @@ impl Global { ) -> (id::BufferId, Option) { profiling::scope!("Device::create_buffer"); - let hub = A::hub(self); - let fid = hub.buffers.prepare(id_in); + let hub = &self.hub; + let fid = hub.buffers.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -220,16 +213,20 @@ impl Global { /// [`device_create_buffer`]: Global::device_create_buffer /// [`usage`]: https://www.w3.org/TR/webgpu/#dom-gputexturedescriptor-usage /// [`wgpu_types::BufferUsages`]: wgt::BufferUsages - pub fn create_buffer_error(&self, id_in: Option) { - let hub = A::hub(self); - let fid = hub.buffers.prepare(id_in); + pub fn create_buffer_error(&self, backend: wgt::Backend, id_in: Option) { + let hub = &self.hub; + let fid = hub.buffers.prepare(backend, id_in); fid.assign_error(); } - pub fn create_render_bundle_error(&self, id_in: Option) { - let hub = A::hub(self); - let fid = hub.render_bundles.prepare(id_in); + pub fn create_render_bundle_error( + &self, + backend: wgt::Backend, + id_in: Option, + ) { + let hub = &self.hub; + let fid = hub.render_bundles.prepare(backend, id_in); fid.assign_error(); } @@ -237,21 +234,21 @@ impl Global { /// Assign `id_in` an error with the given `label`. /// /// See `create_buffer_error` for more context and explanation. - pub fn create_texture_error(&self, id_in: Option) { - let hub = A::hub(self); - let fid = hub.textures.prepare(id_in); + pub fn create_texture_error(&self, backend: wgt::Backend, id_in: Option) { + let hub = &self.hub; + let fid = hub.textures.prepare(backend, id_in); fid.assign_error(); } #[cfg(feature = "replay")] - pub fn device_set_buffer_data( + pub fn device_set_buffer_data( &self, buffer_id: id::BufferId, offset: BufferAddress, data: &[u8], ) -> BufferAccessResult { - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers @@ -291,14 +288,11 @@ impl Global { Ok(()) } - pub fn buffer_destroy( - &self, - buffer_id: id::BufferId, - ) -> Result<(), resource::DestroyError> { + pub fn buffer_destroy(&self, buffer_id: id::BufferId) -> Result<(), resource::DestroyError> { profiling::scope!("Buffer::destroy"); api_log!("Buffer::destroy {buffer_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers @@ -318,11 +312,11 @@ impl Global { buffer.destroy() } - pub fn buffer_drop(&self, buffer_id: id::BufferId) { + pub fn buffer_drop(&self, buffer_id: id::BufferId) { profiling::scope!("Buffer::drop"); api_log!("Buffer::drop {buffer_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; let buffer = match hub.buffers.unregister(buffer_id) { Some(buffer) => buffer, @@ -342,7 +336,7 @@ impl Global { ); } - pub fn device_create_texture( + pub fn device_create_texture( &self, device_id: DeviceId, desc: &resource::TextureDescriptor, @@ -350,9 +344,9 @@ impl Global { ) -> (id::TextureId, Option) { profiling::scope!("Device::create_texture"); - let hub = A::hub(self); + let hub = &self.hub; - let fid = hub.textures.prepare(id_in); + let fid = hub.textures.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -387,7 +381,7 @@ impl Global { /// - `hal_texture` must be created from `device_id` corresponding raw handle. /// - `hal_texture` must be created respecting `desc` /// - `hal_texture` must be initialized - pub unsafe fn create_texture_from_hal( + pub unsafe fn create_texture_from_hal( &self, hal_texture: Box, device_id: DeviceId, @@ -396,9 +390,9 @@ impl Global { ) -> (id::TextureId, Option) { profiling::scope!("Device::create_texture_from_hal"); - let hub = A::hub(self); + let hub = &self.hub; - let fid = hub.textures.prepare(id_in); + let fid = hub.textures.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -444,8 +438,8 @@ impl Global { ) -> (id::BufferId, Option) { profiling::scope!("Device::create_buffer"); - let hub = A::hub(self); - let fid = hub.buffers.prepare(id_in); + let hub = &self.hub; + let fid = hub.buffers.prepare(A::VARIANT, id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -460,7 +454,7 @@ impl Global { trace.add(trace::Action::CreateBuffer(fid.id(), desc.clone())); } - let buffer = device.create_buffer_from_hal(hal_buffer, desc); + let buffer = device.create_buffer_from_hal(Box::new(hal_buffer), desc); let id = fid.assign(buffer); api_log!("Device::create_buffer -> {id:?}"); @@ -474,14 +468,11 @@ impl Global { (id, Some(error)) } - pub fn texture_destroy( - &self, - texture_id: id::TextureId, - ) -> Result<(), resource::DestroyError> { + pub fn texture_destroy(&self, texture_id: id::TextureId) -> Result<(), resource::DestroyError> { profiling::scope!("Texture::destroy"); api_log!("Texture::destroy {texture_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; let texture = hub .textures @@ -496,11 +487,11 @@ impl Global { texture.destroy() } - pub fn texture_drop(&self, texture_id: id::TextureId) { + pub fn texture_drop(&self, texture_id: id::TextureId) { profiling::scope!("Texture::drop"); api_log!("Texture::drop {texture_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_texture) = hub.textures.unregister(texture_id) { #[cfg(feature = "trace")] @@ -510,7 +501,7 @@ impl Global { } } - pub fn texture_create_view( + pub fn texture_create_view( &self, texture_id: id::TextureId, desc: &resource::TextureViewDescriptor, @@ -518,9 +509,9 @@ impl Global { ) -> (id::TextureViewId, Option) { profiling::scope!("Texture::create_view"); - let hub = A::hub(self); + let hub = &self.hub; - let fid = hub.texture_views.prepare(id_in); + let fid = hub.texture_views.prepare(texture_id.backend(), id_in); let error = 'error: { let texture = match hub.textures.get(texture_id) { @@ -557,14 +548,14 @@ impl Global { (id, Some(error)) } - pub fn texture_view_drop( + pub fn texture_view_drop( &self, texture_view_id: id::TextureViewId, ) -> Result<(), resource::TextureViewDestroyError> { profiling::scope!("TextureView::drop"); api_log!("TextureView::drop {texture_view_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_view) = hub.texture_views.unregister(texture_view_id) { #[cfg(feature = "trace")] @@ -575,7 +566,7 @@ impl Global { Ok(()) } - pub fn device_create_sampler( + pub fn device_create_sampler( &self, device_id: DeviceId, desc: &resource::SamplerDescriptor, @@ -583,8 +574,8 @@ impl Global { ) -> (id::SamplerId, Option) { profiling::scope!("Device::create_sampler"); - let hub = A::hub(self); - let fid = hub.samplers.prepare(id_in); + let hub = &self.hub; + let fid = hub.samplers.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -612,11 +603,11 @@ impl Global { (id, Some(error)) } - pub fn sampler_drop(&self, sampler_id: id::SamplerId) { + pub fn sampler_drop(&self, sampler_id: id::SamplerId) { profiling::scope!("Sampler::drop"); api_log!("Sampler::drop {sampler_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_sampler) = hub.samplers.unregister(sampler_id) { #[cfg(feature = "trace")] @@ -626,7 +617,7 @@ impl Global { } } - pub fn device_create_bind_group_layout( + pub fn device_create_bind_group_layout( &self, device_id: DeviceId, desc: &binding_model::BindGroupLayoutDescriptor, @@ -637,8 +628,8 @@ impl Global { ) { profiling::scope!("Device::create_bind_group_layout"); - let hub = A::hub(self); - let fid = hub.bind_group_layouts.prepare(id_in); + let hub = &self.hub; + let fid = hub.bind_group_layouts.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -681,16 +672,16 @@ impl Global { return (id, None); }; - let fid = hub.bind_group_layouts.prepare(id_in); + let fid = hub.bind_group_layouts.prepare(device_id.backend(), id_in); let id = fid.assign_error(); (id, Some(error)) } - pub fn bind_group_layout_drop(&self, bind_group_layout_id: id::BindGroupLayoutId) { + pub fn bind_group_layout_drop(&self, bind_group_layout_id: id::BindGroupLayoutId) { profiling::scope!("BindGroupLayout::drop"); api_log!("BindGroupLayout::drop {bind_group_layout_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_layout) = hub.bind_group_layouts.unregister(bind_group_layout_id) { #[cfg(feature = "trace")] @@ -700,7 +691,7 @@ impl Global { } } - pub fn device_create_pipeline_layout( + pub fn device_create_pipeline_layout( &self, device_id: DeviceId, desc: &binding_model::PipelineLayoutDescriptor, @@ -711,8 +702,8 @@ impl Global { ) { profiling::scope!("Device::create_pipeline_layout"); - let hub = A::hub(self); - let fid = hub.pipeline_layouts.prepare(id_in); + let hub = &self.hub; + let fid = hub.pipeline_layouts.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -764,11 +755,11 @@ impl Global { (id, Some(error)) } - pub fn pipeline_layout_drop(&self, pipeline_layout_id: id::PipelineLayoutId) { + pub fn pipeline_layout_drop(&self, pipeline_layout_id: id::PipelineLayoutId) { profiling::scope!("PipelineLayout::drop"); api_log!("PipelineLayout::drop {pipeline_layout_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_layout) = hub.pipeline_layouts.unregister(pipeline_layout_id) { #[cfg(feature = "trace")] if let Some(t) = _layout.device.trace.lock().as_mut() { @@ -777,7 +768,7 @@ impl Global { } } - pub fn device_create_bind_group( + pub fn device_create_bind_group( &self, device_id: DeviceId, desc: &binding_model::BindGroupDescriptor, @@ -785,8 +776,8 @@ impl Global { ) -> (id::BindGroupId, Option) { profiling::scope!("Device::create_bind_group"); - let hub = A::hub(self); - let fid = hub.bind_groups.prepare(id_in); + let hub = &self.hub; + let fid = hub.bind_groups.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -804,12 +795,12 @@ impl Global { Err(..) => break 'error binding_model::CreateBindGroupError::InvalidLayout, }; - fn map_entry<'a, A: HalApi>( + fn map_entry<'a>( e: &BindGroupEntry<'a>, - buffer_storage: &Storage>, - sampler_storage: &Storage>, - texture_view_storage: &Storage>, - ) -> Result, binding_model::CreateBindGroupError> + buffer_storage: &Storage, + sampler_storage: &Storage, + texture_view_storage: &Storage, + ) -> Result, binding_model::CreateBindGroupError> { let map_buffer = |bb: &BufferBinding| { buffer_storage @@ -904,11 +895,11 @@ impl Global { (id, Some(error)) } - pub fn bind_group_drop(&self, bind_group_id: id::BindGroupId) { + pub fn bind_group_drop(&self, bind_group_id: id::BindGroupId) { profiling::scope!("BindGroup::drop"); api_log!("BindGroup::drop {bind_group_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_bind_group) = hub.bind_groups.unregister(bind_group_id) { #[cfg(feature = "trace")] @@ -932,7 +923,7 @@ impl Global { /// input. /// /// - pub fn device_create_shader_module( + pub fn device_create_shader_module( &self, device_id: DeviceId, desc: &pipeline::ShaderModuleDescriptor, @@ -944,8 +935,8 @@ impl Global { ) { profiling::scope!("Device::create_shader_module"); - let hub = A::hub(self); - let fid = hub.shader_modules.prepare(id_in); + let hub = &self.hub; + let fid = hub.shader_modules.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -1007,7 +998,7 @@ impl Global { /// /// This function passes SPIR-V binary to the backend as-is and can potentially result in a /// driver crash. - pub unsafe fn device_create_shader_module_spirv( + pub unsafe fn device_create_shader_module_spirv( &self, device_id: DeviceId, desc: &pipeline::ShaderModuleDescriptor, @@ -1019,8 +1010,8 @@ impl Global { ) { profiling::scope!("Device::create_shader_module"); - let hub = A::hub(self); - let fid = hub.shader_modules.prepare(id_in); + let hub = &self.hub; + let fid = hub.shader_modules.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -1055,11 +1046,11 @@ impl Global { (id, Some(error)) } - pub fn shader_module_drop(&self, shader_module_id: id::ShaderModuleId) { + pub fn shader_module_drop(&self, shader_module_id: id::ShaderModuleId) { profiling::scope!("ShaderModule::drop"); api_log!("ShaderModule::drop {shader_module_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(shader_module) = hub.shader_modules.unregister(shader_module_id) { #[cfg(feature = "trace")] @@ -1070,7 +1061,7 @@ impl Global { } } - pub fn device_create_command_encoder( + pub fn device_create_command_encoder( &self, device_id: DeviceId, desc: &wgt::CommandEncoderDescriptor(command_buffer_id.into_command_encoder_id()) + self.command_encoder_drop(command_buffer_id.into_command_encoder_id()) } pub fn device_create_render_bundle_encoder( @@ -1140,7 +1132,7 @@ impl Global { (Box::into_raw(Box::new(encoder)), error) } - pub fn render_bundle_encoder_finish( + pub fn render_bundle_encoder_finish( &self, bundle_encoder: command::RenderBundleEncoder, desc: &command::RenderBundleDescriptor, @@ -1148,9 +1140,11 @@ impl Global { ) -> (id::RenderBundleId, Option) { profiling::scope!("RenderBundleEncoder::finish"); - let hub = A::hub(self); + let hub = &self.hub; - let fid = hub.render_bundles.prepare(id_in); + let fid = hub + .render_bundles + .prepare(bundle_encoder.parent().backend(), id_in); let error = 'error: { let device = match hub.devices.get(bundle_encoder.parent()) { @@ -1191,11 +1185,11 @@ impl Global { (id, Some(error)) } - pub fn render_bundle_drop(&self, render_bundle_id: id::RenderBundleId) { + pub fn render_bundle_drop(&self, render_bundle_id: id::RenderBundleId) { profiling::scope!("RenderBundle::drop"); api_log!("RenderBundle::drop {render_bundle_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_bundle) = hub.render_bundles.unregister(render_bundle_id) { #[cfg(feature = "trace")] @@ -1205,7 +1199,7 @@ impl Global { } } - pub fn device_create_query_set( + pub fn device_create_query_set( &self, device_id: DeviceId, desc: &resource::QuerySetDescriptor, @@ -1213,8 +1207,8 @@ impl Global { ) -> (id::QuerySetId, Option) { profiling::scope!("Device::create_query_set"); - let hub = A::hub(self); - let fid = hub.query_sets.prepare(id_in); + let hub = &self.hub; + let fid = hub.query_sets.prepare(device_id.backend(), id_in); let error = 'error: { let device = match hub.devices.get(device_id) { @@ -1245,11 +1239,11 @@ impl Global { (id, Some(error)) } - pub fn query_set_drop(&self, query_set_id: id::QuerySetId) { + pub fn query_set_drop(&self, query_set_id: id::QuerySetId) { profiling::scope!("QuerySet::drop"); api_log!("QuerySet::drop {query_set_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_query_set) = hub.query_sets.unregister(query_set_id) { #[cfg(feature = "trace")] @@ -1259,7 +1253,7 @@ impl Global { } } - pub fn device_create_render_pipeline( + pub fn device_create_render_pipeline( &self, device_id: DeviceId, desc: &pipeline::RenderPipelineDescriptor, @@ -1271,12 +1265,12 @@ impl Global { ) { profiling::scope!("Device::create_render_pipeline"); - let hub = A::hub(self); + let hub = &self.hub; let missing_implicit_pipeline_ids = desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none(); - let fid = hub.render_pipelines.prepare(id_in); + let fid = hub.render_pipelines.prepare(device_id.backend(), id_in); let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub)); let error = 'error: { @@ -1457,7 +1451,7 @@ impl Global { /// Get an ID of one of the bind group layouts. The ID adds a refcount, /// which needs to be released by calling `bind_group_layout_drop`. - pub fn render_pipeline_get_bind_group_layout( + pub fn render_pipeline_get_bind_group_layout( &self, pipeline_id: id::RenderPipelineId, index: u32, @@ -1466,7 +1460,7 @@ impl Global { id::BindGroupLayoutId, Option, ) { - let hub = A::hub(self); + let hub = &self.hub; let error = 'error: { let pipeline = match hub.render_pipelines.get(pipeline_id) { @@ -1474,7 +1468,10 @@ impl Global { Err(_) => break 'error binding_model::GetBindGroupLayoutError::InvalidPipeline, }; let id = match pipeline.layout.bind_group_layouts.get(index as usize) { - Some(bg) => hub.bind_group_layouts.prepare(id_in).assign(bg.clone()), + Some(bg) => hub + .bind_group_layouts + .prepare(pipeline_id.backend(), id_in) + .assign(bg.clone()), None => { break 'error binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index) } @@ -1482,15 +1479,18 @@ impl Global { return (id, None); }; - let id = hub.bind_group_layouts.prepare(id_in).assign_error(); + let id = hub + .bind_group_layouts + .prepare(pipeline_id.backend(), id_in) + .assign_error(); (id, Some(error)) } - pub fn render_pipeline_drop(&self, render_pipeline_id: id::RenderPipelineId) { + pub fn render_pipeline_drop(&self, render_pipeline_id: id::RenderPipelineId) { profiling::scope!("RenderPipeline::drop"); api_log!("RenderPipeline::drop {render_pipeline_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_pipeline) = hub.render_pipelines.unregister(render_pipeline_id) { #[cfg(feature = "trace")] @@ -1500,7 +1500,7 @@ impl Global { } } - pub fn device_create_compute_pipeline( + pub fn device_create_compute_pipeline( &self, device_id: DeviceId, desc: &pipeline::ComputePipelineDescriptor, @@ -1512,12 +1512,12 @@ impl Global { ) { profiling::scope!("Device::create_compute_pipeline"); - let hub = A::hub(self); + let hub = &self.hub; let missing_implicit_pipeline_ids = desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none(); - let fid = hub.compute_pipelines.prepare(id_in); + let fid = hub.compute_pipelines.prepare(device_id.backend(), id_in); let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub)); let error = 'error: { @@ -1651,7 +1651,7 @@ impl Global { /// Get an ID of one of the bind group layouts. The ID adds a refcount, /// which needs to be released by calling `bind_group_layout_drop`. - pub fn compute_pipeline_get_bind_group_layout( + pub fn compute_pipeline_get_bind_group_layout( &self, pipeline_id: id::ComputePipelineId, index: u32, @@ -1660,7 +1660,7 @@ impl Global { id::BindGroupLayoutId, Option, ) { - let hub = A::hub(self); + let hub = &self.hub; let error = 'error: { let pipeline = match hub.compute_pipelines.get(pipeline_id) { @@ -1669,7 +1669,10 @@ impl Global { }; let id = match pipeline.layout.bind_group_layouts.get(index as usize) { - Some(bg) => hub.bind_group_layouts.prepare(id_in).assign(bg.clone()), + Some(bg) => hub + .bind_group_layouts + .prepare(pipeline_id.backend(), id_in) + .assign(bg.clone()), None => { break 'error binding_model::GetBindGroupLayoutError::InvalidGroupIndex(index) } @@ -1678,15 +1681,18 @@ impl Global { return (id, None); }; - let id = hub.bind_group_layouts.prepare(id_in).assign_error(); + let id = hub + .bind_group_layouts + .prepare(pipeline_id.backend(), id_in) + .assign_error(); (id, Some(error)) } - pub fn compute_pipeline_drop(&self, compute_pipeline_id: id::ComputePipelineId) { + pub fn compute_pipeline_drop(&self, compute_pipeline_id: id::ComputePipelineId) { profiling::scope!("ComputePipeline::drop"); api_log!("ComputePipeline::drop {compute_pipeline_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(_pipeline) = hub.compute_pipelines.unregister(compute_pipeline_id) { #[cfg(feature = "trace")] @@ -1699,7 +1705,7 @@ impl Global { /// # Safety /// The `data` argument of `desc` must have been returned by /// [Self::pipeline_cache_get_data] for the same adapter - pub unsafe fn device_create_pipeline_cache( + pub unsafe fn device_create_pipeline_cache( &self, device_id: DeviceId, desc: &pipeline::PipelineCacheDescriptor<'_>, @@ -1710,9 +1716,9 @@ impl Global { ) { profiling::scope!("Device::create_pipeline_cache"); - let hub = A::hub(self); + let hub = &self.hub; - let fid = hub.pipeline_caches.prepare(id_in); + let fid = hub.pipeline_caches.prepare(device_id.backend(), id_in); let error: pipeline::CreatePipelineCacheError = 'error: { let device = match hub.devices.get(device_id) { Ok(device) => device, @@ -1744,11 +1750,11 @@ impl Global { (id, Some(error)) } - pub fn pipeline_cache_drop(&self, pipeline_cache_id: id::PipelineCacheId) { + pub fn pipeline_cache_drop(&self, pipeline_cache_id: id::PipelineCacheId) { profiling::scope!("PipelineCache::drop"); api_log!("PipelineCache::drop {pipeline_cache_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(cache) = hub.pipeline_caches.unregister(pipeline_cache_id) { #[cfg(feature = "trace")] @@ -1759,7 +1765,7 @@ impl Global { } } - pub fn surface_configure( + pub fn surface_configure( &self, surface_id: SurfaceId, device_id: DeviceId, @@ -1886,7 +1892,7 @@ impl Global { // User callbacks must not be called while we are holding locks. let user_callbacks; { - let hub = A::hub(self); + let hub = &self.hub; let surface_guard = self.surfaces.read(); let device = match hub.devices.get(device_id) { @@ -1989,7 +1995,7 @@ impl Global { // // https://github.com/gfx-rs/wgpu/issues/4105 - let surface_raw = surface.raw(A::VARIANT).unwrap(); + let surface_raw = surface.raw(device_id.backend()).unwrap(); match unsafe { surface_raw.configure(device.raw(), &hal_config) } { Ok(()) => (), Err(error) => { @@ -2008,7 +2014,7 @@ impl Global { let mut presentation = surface.presentation.lock(); *presentation = Some(present::Presentation { - device: super::any_device::AnyDevice::new(device), + device, config: config.clone(), acquired_texture: None, }); @@ -2024,14 +2030,14 @@ impl Global { /// Check `device_id` for freeable resources and completed buffer mappings. /// /// Return `queue_empty` indicating whether there are more queue submissions still in flight. - pub fn device_poll( + pub fn device_poll( &self, device_id: DeviceId, maintain: wgt::Maintain, ) -> Result { api_log!("Device::poll {maintain:?}"); - let hub = A::hub(self); + let hub = &self.hub; let device = hub .devices .get(device_id) @@ -2047,8 +2053,8 @@ impl Global { Ok(queue_empty) } - fn poll_single_device( - device: &crate::device::Device, + fn poll_single_device( + device: &crate::device::Device, maintain: wgt::Maintain, ) -> Result { let snatch_guard = device.snatchable_lock.read(); @@ -2065,25 +2071,26 @@ impl Global { }) } - /// Poll all devices belonging to the backend `A`. + /// Poll all devices belonging to the specified backend. /// /// If `force_wait` is true, block until all buffer mappings are done. /// /// Return `all_queue_empty` indicating whether there are more queue /// submissions still in flight. - fn poll_all_devices_of_api( + fn poll_all_devices_of_api( &self, + backend: wgt::Backend, force_wait: bool, closures: &mut UserClosures, ) -> Result { profiling::scope!("poll_device"); - let hub = A::hub(self); + let hub = &self.hub; let mut all_queue_empty = true; { let device_guard = hub.devices.read(); - for (_id, device) in device_guard.iter(A::VARIANT) { + for (_id, device) in device_guard.iter(backend) { let maintain = if force_wait { wgt::Maintain::Wait } else { @@ -2118,22 +2125,22 @@ impl Global { #[cfg(vulkan)] { all_queue_empty &= - self.poll_all_devices_of_api::(force_wait, &mut closures)?; + self.poll_all_devices_of_api(wgt::Backend::Vulkan, force_wait, &mut closures)?; } #[cfg(metal)] { all_queue_empty &= - self.poll_all_devices_of_api::(force_wait, &mut closures)?; + self.poll_all_devices_of_api(wgt::Backend::Metal, force_wait, &mut closures)?; } #[cfg(dx12)] { all_queue_empty &= - self.poll_all_devices_of_api::(force_wait, &mut closures)?; + self.poll_all_devices_of_api(wgt::Backend::Dx12, force_wait, &mut closures)?; } #[cfg(gles)] { all_queue_empty &= - self.poll_all_devices_of_api::(force_wait, &mut closures)?; + self.poll_all_devices_of_api(wgt::Backend::Gl, force_wait, &mut closures)?; } closures.fire(); @@ -2141,10 +2148,10 @@ impl Global { Ok(all_queue_empty) } - pub fn device_start_capture(&self, id: DeviceId) { + pub fn device_start_capture(&self, id: DeviceId) { api_log!("Device::start_capture"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(id) { if !device.is_valid() { @@ -2154,10 +2161,10 @@ impl Global { } } - pub fn device_stop_capture(&self, id: DeviceId) { + pub fn device_stop_capture(&self, id: DeviceId) { api_log!("Device::stop_capture"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(id) { if !device.is_valid() { @@ -2170,15 +2177,15 @@ impl Global { // This is a test-only function to force the device into an // invalid state by inserting an error value in its place in // the registry. - pub fn device_make_invalid(&self, device_id: DeviceId) { - let hub = A::hub(self); + pub fn device_make_invalid(&self, device_id: DeviceId) { + let hub = &self.hub; hub.devices.force_replace_with_error(device_id); } - pub fn pipeline_cache_get_data(&self, id: id::PipelineCacheId) -> Option> { + pub fn pipeline_cache_get_data(&self, id: id::PipelineCacheId) -> Option> { use crate::pipeline_cache; api_log!("PipelineCache::get_data"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(cache) = hub.pipeline_caches.get(id) { // TODO: Is this check needed? @@ -2204,11 +2211,11 @@ impl Global { None } - pub fn device_drop(&self, device_id: DeviceId) { + pub fn device_drop(&self, device_id: DeviceId) { profiling::scope!("Device::drop"); api_log!("Device::drop {device_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(device) = hub.devices.unregister(device_id) { let device_lost_closure = device.lock_life().device_lost_closure.take(); if let Some(closure) = device_lost_closure { @@ -2228,12 +2235,12 @@ impl Global { // This closure will be called exactly once during "lose the device", // or when it is replaced. - pub fn device_set_device_lost_closure( + pub fn device_set_device_lost_closure( &self, device_id: DeviceId, device_lost_closure: DeviceLostClosure, ) { - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(device_id) { let mut life_tracker = device.lock_life(); @@ -2253,10 +2260,10 @@ impl Global { } } - pub fn device_destroy(&self, device_id: DeviceId) { + pub fn device_destroy(&self, device_id: DeviceId) { api_log!("Device::destroy {device_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(device_id) { // Follow the steps at @@ -2279,21 +2286,18 @@ impl Global { } } - pub fn device_mark_lost(&self, device_id: DeviceId, message: &str) { + pub fn device_mark_lost(&self, device_id: DeviceId, message: &str) { api_log!("Device::mark_lost {device_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(device_id) { device.lose(message); } } - pub fn device_get_internal_counters( - &self, - device_id: DeviceId, - ) -> wgt::InternalCounters { - let hub = A::hub(self); + pub fn device_get_internal_counters(&self, device_id: DeviceId) -> wgt::InternalCounters { + let hub = &self.hub; if let Ok(device) = hub.devices.get(device_id) { wgt::InternalCounters { hal: device.get_hal_counters(), @@ -2304,28 +2308,28 @@ impl Global { } } - pub fn device_generate_allocator_report( + pub fn device_generate_allocator_report( &self, device_id: DeviceId, ) -> Option { - let hub = A::hub(self); + let hub = &self.hub; hub.devices .get(device_id) .ok() .and_then(|device| device.generate_allocator_report()) } - pub fn queue_drop(&self, queue_id: QueueId) { + pub fn queue_drop(&self, queue_id: QueueId) { profiling::scope!("Queue::drop"); api_log!("Queue::drop {queue_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; if let Some(queue) = hub.queues.unregister(queue_id) { drop(queue); } } - pub fn buffer_map_async( + pub fn buffer_map_async( &self, buffer_id: id::BufferId, offset: BufferAddress, @@ -2335,7 +2339,7 @@ impl Global { profiling::scope!("Buffer::map_async"); api_log!("Buffer::map_async {buffer_id:?} offset {offset:?} size {size:?} op: {op:?}"); - let hub = A::hub(self); + let hub = &self.hub; let op_and_err = 'error: { let buffer = match hub.buffers.get(buffer_id) { @@ -2360,7 +2364,7 @@ impl Global { Ok(()) } - pub fn buffer_get_mapped_range( + pub fn buffer_get_mapped_range( &self, buffer_id: id::BufferId, offset: BufferAddress, @@ -2369,7 +2373,7 @@ impl Global { profiling::scope!("Buffer::get_mapped_range"); api_log!("Buffer::get_mapped_range {buffer_id:?} offset {offset:?} size {size:?}"); - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers @@ -2441,11 +2445,11 @@ impl Global { } } } - pub fn buffer_unmap(&self, buffer_id: id::BufferId) -> BufferAccessResult { + pub fn buffer_unmap(&self, buffer_id: id::BufferId) -> BufferAccessResult { profiling::scope!("unmap", "Buffer"); api_log!("Buffer::unmap {buffer_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 1ee84be933..e6aed78a08 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -3,7 +3,6 @@ use crate::{ queue::{EncoderInFlight, SubmittedWorkDoneClosure, TempResource}, DeviceError, DeviceLostClosure, }, - hal_api::HalApi, resource::{self, Buffer, Texture, Trackable}, snatch::SnatchGuard, SubmissionIndex, @@ -22,7 +21,7 @@ use thiserror::Error; /// /// [`wgpu_hal`]: hal /// [`ResourceInfo::submission_index`]: crate::resource::ResourceInfo -struct ActiveSubmission { +struct ActiveSubmission { /// The index of the submission we track. /// /// When `Device::fence`'s value is greater than or equal to this, our queue @@ -30,10 +29,10 @@ struct ActiveSubmission { index: SubmissionIndex, /// Temporary resources to be freed once this queue submission has completed. - temp_resources: Vec>, + temp_resources: Vec, /// Buffers to be mapped once this submission has completed. - mapped: Vec>>, + mapped: Vec>, /// Command buffers used by this submission, and the encoder that owns them. /// @@ -47,18 +46,18 @@ struct ActiveSubmission { /// the command encoder is recycled. /// /// [`wgpu_hal::Queue::submit`]: hal::Queue::submit - encoders: Vec>, + encoders: Vec, /// List of queue "on_submitted_work_done" closures to be called once this /// submission has completed. work_done_closures: SmallVec<[SubmittedWorkDoneClosure; 1]>, } -impl ActiveSubmission { +impl ActiveSubmission { /// Returns true if this submission contains the given buffer. /// /// This only uses constant-time operations. - pub fn contains_buffer(&self, buffer: &Buffer) -> bool { + pub fn contains_buffer(&self, buffer: &Buffer) -> bool { for encoder in &self.encoders { // The ownership location of buffers depends on where the command encoder // came from. If it is the staging command encoder on the queue, it is @@ -83,7 +82,7 @@ impl ActiveSubmission { /// Returns true if this submission contains the given texture. /// /// This only uses constant-time operations. - pub fn contains_texture(&self, texture: &Texture) -> bool { + pub fn contains_texture(&self, texture: &Texture) -> bool { for encoder in &self.encoders { // The ownership location of textures depends on where the command encoder // came from. If it is the staging command encoder on the queue, it is @@ -150,11 +149,11 @@ pub enum WaitIdleError { /// /// Only calling `Global::buffer_map_async` clones a new `Arc` for the /// buffer. This new `Arc` is only dropped by `handle_mapping`. -pub(crate) struct LifetimeTracker { +pub(crate) struct LifetimeTracker { /// Buffers for which a call to [`Buffer::map_async`] has succeeded, but /// which haven't been examined by `triage_mapped` yet to decide when they /// can be mapped. - mapped: Vec>>, + mapped: Vec>, /// Resources used by queue submissions still in flight. One entry per /// submission, with older submissions appearing before younger. @@ -162,11 +161,11 @@ pub(crate) struct LifetimeTracker { /// Entries are added by `track_submission` and drained by /// `LifetimeTracker::triage_submissions`. Lots of methods contribute data /// to particular entries. - active: Vec>, + active: Vec, /// Buffers the user has asked us to map, and which are not used by any /// queue submission still in flight. - ready_to_map: Vec>>, + ready_to_map: Vec>, /// Queue "on_submitted_work_done" closures that were initiated for while there is no /// currently pending submissions. These cannot be immediately invoked as they @@ -180,7 +179,7 @@ pub(crate) struct LifetimeTracker { pub device_lost_closure: Option, } -impl LifetimeTracker { +impl LifetimeTracker { pub fn new() -> Self { Self { mapped: Vec::new(), @@ -200,8 +199,8 @@ impl LifetimeTracker { pub fn track_submission( &mut self, index: SubmissionIndex, - temp_resources: impl Iterator>, - encoders: Vec>, + temp_resources: impl Iterator, + encoders: Vec, ) { self.active.push(ActiveSubmission { index, @@ -212,16 +211,13 @@ impl LifetimeTracker { }); } - pub(crate) fn map(&mut self, value: &Arc>) { + pub(crate) fn map(&mut self, value: &Arc) { self.mapped.push(value.clone()); } /// Returns the submission index of the most recent submission that uses the /// given buffer. - pub fn get_buffer_latest_submission_index( - &self, - buffer: &Buffer, - ) -> Option { + pub fn get_buffer_latest_submission_index(&self, buffer: &Buffer) -> Option { // We iterate in reverse order, so that we can bail out early as soon // as we find a hit. self.active.iter().rev().find_map(|submission| { @@ -237,7 +233,7 @@ impl LifetimeTracker { /// given texture. pub fn get_texture_latest_submission_index( &self, - texture: &Texture, + texture: &Texture, ) -> Option { // We iterate in reverse order, so that we can bail out early as soon // as we find a hit. @@ -295,7 +291,7 @@ impl LifetimeTracker { pub fn schedule_resource_destruction( &mut self, - temp_resource: TempResource, + temp_resource: TempResource, last_submit_index: SubmissionIndex, ) { let resources = self diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c6f88b2634..ac35ec7530 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1,6 +1,5 @@ use crate::{ binding_model, - hal_api::HalApi, hub::Hub, id::{BindGroupLayoutId, PipelineLayoutId}, resource::{ @@ -19,7 +18,6 @@ use wgt::{BufferAddress, DeviceLostReason, TextureFormat}; use std::num::NonZeroU32; -pub mod any_device; pub(crate) mod bgl; pub mod global; mod life; @@ -299,9 +297,9 @@ impl DeviceLostClosure { } } -fn map_buffer( +fn map_buffer( raw: &dyn hal::DynDevice, - buffer: &Buffer, + buffer: &Buffer, offset: BufferAddress, size: BufferAddress, kind: HostMap, @@ -434,13 +432,21 @@ pub struct ImplicitPipelineIds<'a> { } impl ImplicitPipelineIds<'_> { - fn prepare(self, hub: &Hub) -> ImplicitPipelineContext { + fn prepare(self, hub: &Hub) -> ImplicitPipelineContext { + let backend = self.root_id.backend(); ImplicitPipelineContext { - root_id: hub.pipeline_layouts.prepare(Some(self.root_id)).into_id(), + root_id: hub + .pipeline_layouts + .prepare(backend, Some(self.root_id)) + .into_id(), group_ids: self .group_ids .iter() - .map(|id_in| hub.bind_group_layouts.prepare(Some(*id_in)).into_id()) + .map(|id_in| { + hub.bind_group_layouts + .prepare(backend, Some(*id_in)) + .into_id() + }) .collect(), } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index cca59e0b1a..deab6bff21 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -10,7 +10,6 @@ use crate::{ device::{DeviceError, WaitIdleError}, get_lowest_common_denom, global::Global, - hal_api::HalApi, hal_label, id::{self, QueueId}, init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange}, @@ -37,13 +36,13 @@ use thiserror::Error; use super::Device; -pub struct Queue { +pub struct Queue { raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, } -impl Queue { - pub(crate) fn new(device: Arc>, raw: Box) -> Self { +impl Queue { + pub(crate) fn new(device: Arc, raw: Box) -> Self { Queue { raw: ManuallyDrop::new(raw), device, @@ -55,17 +54,17 @@ impl Queue { } } -crate::impl_resource_type_generic!(Queue); +crate::impl_resource_type!(Queue); // TODO: https://github.com/gfx-rs/wgpu/issues/4014 -impl Labeled for Queue { +impl Labeled for Queue { fn label(&self) -> &str { "" } } crate::impl_parent_device!(Queue); -crate::impl_storage_item_generic!(Queue); +crate::impl_storage_item!(Queue); -impl Drop for Queue { +impl Drop for Queue { fn drop(&mut self) { resource_log!("Drop {}", self.error_ident()); // SAFETY: we never access `self.raw` beyond this point. @@ -141,10 +140,10 @@ impl SubmittedWorkDoneClosure { /// - `ActiveSubmission::temp_resources`: temporary resources used by a queue /// submission, to be freed when it completes #[derive(Debug)] -pub enum TempResource { - StagingBuffer(FlushedStagingBuffer), - DestroyedBuffer(DestroyedBuffer), - DestroyedTexture(DestroyedTexture), +pub enum TempResource { + StagingBuffer(FlushedStagingBuffer), + DestroyedBuffer(DestroyedBuffer), + DestroyedTexture(DestroyedTexture), } /// A series of raw [`CommandBuffer`]s that have been submitted to a @@ -152,18 +151,18 @@ pub enum TempResource { /// /// [`CommandBuffer`]: hal::Api::CommandBuffer /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder -pub(crate) struct EncoderInFlight { +pub(crate) struct EncoderInFlight { raw: Box, cmd_buffers: Vec>, - pub(crate) trackers: Tracker, + pub(crate) trackers: Tracker, /// These are the buffers that have been tracked by `PendingWrites`. - pub(crate) pending_buffers: FastHashMap>>, + pub(crate) pending_buffers: FastHashMap>, /// These are the textures that have been tracked by `PendingWrites`. - pub(crate) pending_textures: FastHashMap>>, + pub(crate) pending_textures: FastHashMap>, } -impl EncoderInFlight { +impl EncoderInFlight { /// Free all of our command buffers. /// /// Return the command encoder, fully reset and ready to be @@ -203,7 +202,7 @@ impl EncoderInFlight { /// /// All uses of [`StagingBuffer`]s end up here. #[derive(Debug)] -pub(crate) struct PendingWrites { +pub(crate) struct PendingWrites { pub command_encoder: Box, /// True if `command_encoder` is in the "recording" state, as @@ -213,12 +212,12 @@ pub(crate) struct PendingWrites { /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub is_recording: bool, - temp_resources: Vec>, - dst_buffers: FastHashMap>>, - dst_textures: FastHashMap>>, + temp_resources: Vec, + dst_buffers: FastHashMap>, + dst_textures: FastHashMap>, } -impl PendingWrites { +impl PendingWrites { pub fn new(command_encoder: Box) -> Self { Self { command_encoder, @@ -240,29 +239,29 @@ impl PendingWrites { self.temp_resources.clear(); } - pub fn insert_buffer(&mut self, buffer: &Arc>) { + pub fn insert_buffer(&mut self, buffer: &Arc) { self.dst_buffers .insert(buffer.tracker_index(), buffer.clone()); } - pub fn insert_texture(&mut self, texture: &Arc>) { + pub fn insert_texture(&mut self, texture: &Arc) { self.dst_textures .insert(texture.tracker_index(), texture.clone()); } - pub fn contains_buffer(&self, buffer: &Arc>) -> bool { + pub fn contains_buffer(&self, buffer: &Arc) -> bool { self.dst_buffers.contains_key(&buffer.tracker_index()) } - pub fn contains_texture(&self, texture: &Arc>) -> bool { + pub fn contains_texture(&self, texture: &Arc) -> bool { self.dst_textures.contains_key(&texture.tracker_index()) } - pub fn consume_temp(&mut self, resource: TempResource) { + pub fn consume_temp(&mut self, resource: TempResource) { self.temp_resources.push(resource); } - pub fn consume(&mut self, buffer: FlushedStagingBuffer) { + pub fn consume(&mut self, buffer: FlushedStagingBuffer) { self.temp_resources .push(TempResource::StagingBuffer(buffer)); } @@ -272,7 +271,7 @@ impl PendingWrites { command_allocator: &CommandAllocator, device: &dyn hal::DynDevice, queue: &dyn hal::DynQueue, - ) -> Result>, DeviceError> { + ) -> Result, DeviceError> { if self.is_recording { let pending_buffers = mem::take(&mut self.dst_buffers); let pending_textures = mem::take(&mut self.dst_textures); @@ -362,7 +361,7 @@ pub enum QueueSubmitError { //TODO: move out common parts of write_xxx. impl Global { - pub fn queue_write_buffer( + pub fn queue_write_buffer( &self, queue_id: QueueId, buffer_id: id::BufferId, @@ -372,7 +371,7 @@ impl Global { profiling::scope!("Queue::write_buffer"); api_log!("Queue::write_buffer {buffer_id:?} {}bytes", data.len()); - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers @@ -433,14 +432,14 @@ impl Global { result } - pub fn queue_create_staging_buffer( + pub fn queue_create_staging_buffer( &self, queue_id: QueueId, buffer_size: wgt::BufferSize, id_in: Option, ) -> Result<(id::StagingBufferId, NonNull), QueueWriteError> { profiling::scope!("Queue::create_staging_buffer"); - let hub = A::hub(self); + let hub = &self.hub; let queue = hub .queues @@ -452,14 +451,14 @@ impl Global { let staging_buffer = StagingBuffer::new(device, buffer_size)?; let ptr = unsafe { staging_buffer.ptr() }; - let fid = hub.staging_buffers.prepare(id_in); + let fid = hub.staging_buffers.prepare(queue_id.backend(), id_in); let id = fid.assign(Arc::new(staging_buffer)); resource_log!("Queue::create_staging_buffer {id:?}"); Ok((id, ptr)) } - pub fn queue_write_staging_buffer( + pub fn queue_write_staging_buffer( &self, queue_id: QueueId, buffer_id: id::BufferId, @@ -467,7 +466,7 @@ impl Global { staging_buffer_id: id::StagingBufferId, ) -> Result<(), QueueWriteError> { profiling::scope!("Queue::write_staging_buffer"); - let hub = A::hub(self); + let hub = &self.hub; let queue = hub .queues @@ -503,7 +502,7 @@ impl Global { result } - pub fn queue_validate_write_buffer( + pub fn queue_validate_write_buffer( &self, _queue_id: QueueId, buffer_id: id::BufferId, @@ -511,7 +510,7 @@ impl Global { buffer_size: wgt::BufferSize, ) -> Result<(), QueueWriteError> { profiling::scope!("Queue::validate_write_buffer"); - let hub = A::hub(self); + let hub = &self.hub; let buffer = hub .buffers @@ -523,9 +522,9 @@ impl Global { Ok(()) } - fn queue_validate_write_buffer_impl( + fn queue_validate_write_buffer_impl( &self, - buffer: &Buffer, + buffer: &Buffer, buffer_offset: u64, buffer_size: wgt::BufferSize, ) -> Result<(), TransferError> { @@ -548,16 +547,16 @@ impl Global { Ok(()) } - fn queue_write_staging_buffer_impl( + fn queue_write_staging_buffer_impl( &self, - queue: &Arc>, - device: &Arc>, - pending_writes: &mut PendingWrites, - staging_buffer: &FlushedStagingBuffer, + queue: &Arc, + device: &Arc, + pending_writes: &mut PendingWrites, + staging_buffer: &FlushedStagingBuffer, buffer_id: id::BufferId, buffer_offset: u64, ) -> Result<(), QueueWriteError> { - let hub = A::hub(self); + let hub = &self.hub; let dst = hub .buffers @@ -606,7 +605,7 @@ impl Global { Ok(()) } - pub fn queue_write_texture( + pub fn queue_write_texture( &self, queue_id: QueueId, destination: &ImageCopyTexture, @@ -617,7 +616,7 @@ impl Global { profiling::scope!("Queue::write_texture"); api_log!("Queue::write_texture {:?} {size:?}", destination.texture); - let hub = A::hub(self); + let hub = &self.hub; let queue = hub .queues @@ -849,7 +848,7 @@ impl Global { } #[cfg(webgl)] - pub fn queue_copy_external_image_to_texture( + pub fn queue_copy_external_image_to_texture( &self, queue_id: QueueId, source: &wgt::ImageCopyExternalImage, @@ -858,7 +857,7 @@ impl Global { ) -> Result<(), QueueWriteError> { profiling::scope!("Queue::copy_external_image_to_texture"); - let hub = A::hub(self); + let hub = &self.hub; let queue = hub .queues @@ -1039,7 +1038,7 @@ impl Global { Ok(()) } - pub fn queue_submit( + pub fn queue_submit( &self, queue_id: QueueId, command_buffer_ids: &[id::CommandBufferId], @@ -1048,7 +1047,7 @@ impl Global { api_log!("Queue::submit {queue_id:?}"); let (submit_index, callbacks) = { - let hub = A::hub(self); + let hub = &self.hub; let queue = hub .queues @@ -1186,13 +1185,13 @@ impl Global { //Note: locking the trackers has to be done after the storages let mut trackers = device.trackers.lock(); - baked.initialize_buffer_memory(&mut *trackers, &snatch_guard)?; - baked.initialize_texture_memory(&mut *trackers, device, &snatch_guard)?; + baked.initialize_buffer_memory(&mut trackers, &snatch_guard)?; + baked.initialize_texture_memory(&mut trackers, device, &snatch_guard)?; //Note: stateless trackers are not merged: // device already knows these resources exist. CommandBuffer::insert_barriers_from_device_tracker( baked.encoder.as_mut(), - &mut *trackers, + &mut trackers, &baked.trackers, &snatch_guard, ); @@ -1353,18 +1352,15 @@ impl Global { Ok(submit_index) } - pub fn queue_get_timestamp_period( - &self, - queue_id: QueueId, - ) -> Result { - let hub = A::hub(self); + pub fn queue_get_timestamp_period(&self, queue_id: QueueId) -> Result { + let hub = &self.hub; match hub.queues.get(queue_id) { Ok(queue) => Ok(unsafe { queue.raw().get_timestamp_period() }), Err(_) => Err(InvalidQueue), } } - pub fn queue_on_submitted_work_done( + pub fn queue_on_submitted_work_done( &self, queue_id: QueueId, closure: SubmittedWorkDoneClosure, @@ -1372,7 +1368,7 @@ impl Global { api_log!("Queue::on_submitted_work_done {queue_id:?}"); //TODO: flush pending writes - let hub = A::hub(self); + let hub = &self.hub; match hub.queues.get(queue_id) { Ok(queue) => queue.device.lock_life().add_work_done_closure(closure), Err(_) => return Err(InvalidQueue), diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index a7ce999407..5f50d38c8b 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -11,7 +11,6 @@ use crate::{ AttachmentData, DeviceLostInvocation, HostMap, MissingDownlevelFlags, MissingFeatures, RenderPassContext, CLEANUP_WAIT_MS, }, - hal_api::HalApi, hal_label, init_tracker::{ BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange, @@ -77,10 +76,10 @@ use super::{ /// Important: /// 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 { +pub struct Device { raw: ManuallyDrop>, pub(crate) adapter: Arc, - pub(crate) queue: OnceCell>>, + pub(crate) queue: OnceCell>, queue_to_drop: OnceCell>, pub(crate) zero_buffer: ManuallyDrop>, /// The `label` from the descriptor used to create the resource. @@ -130,30 +129,30 @@ pub struct Device { /// /// Has to be locked temporarily only (locked last) /// and never before pending_writes - pub(crate) trackers: Mutex>, + pub(crate) trackers: Mutex, pub(crate) tracker_indices: TrackerIndexAllocators, // Life tracker should be locked right after the device and before anything else. - life_tracker: Mutex>, + life_tracker: Mutex, /// Pool of bind group layouts, allowing deduplication. - pub(crate) bgl_pool: ResourcePool>, + pub(crate) bgl_pool: ResourcePool, pub(crate) alignments: hal::Alignments, pub(crate) limits: wgt::Limits, pub(crate) features: wgt::Features, pub(crate) downlevel: wgt::DownlevelCapabilities, pub(crate) instance_flags: wgt::InstanceFlags, - pub(crate) pending_writes: Mutex>>, - pub(crate) deferred_destroy: Mutex>>, + pub(crate) pending_writes: Mutex>, + pub(crate) deferred_destroy: Mutex>, #[cfg(feature = "trace")] pub(crate) trace: Mutex>, - pub(crate) usage_scopes: UsageScopePool, + pub(crate) usage_scopes: UsageScopePool, } -pub(crate) enum DeferredDestroy { - TextureView(Weak>), - BindGroup(Weak>), +pub(crate) enum DeferredDestroy { + TextureView(Weak), + BindGroup(Weak), } -impl std::fmt::Debug for Device { +impl std::fmt::Debug for Device { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Device") .field("label", &self.label()) @@ -164,7 +163,7 @@ impl std::fmt::Debug for Device { } } -impl Drop for Device { +impl Drop for Device { fn drop(&mut self) { resource_log!("Drop {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -194,7 +193,7 @@ pub enum CreateDeviceError { FailedToCreateZeroBuffer(#[from] DeviceError), } -impl Device { +impl Device { pub(crate) fn raw(&self) -> &dyn hal::DynDevice { self.raw.as_ref() } @@ -218,7 +217,7 @@ impl Device { } } -impl Device { +impl Device { pub(crate) fn new( raw_device: Box, raw_queue: &dyn hal::DynQueue, @@ -238,7 +237,7 @@ impl Device { let pending_encoder = command_allocator .acquire_encoder(raw_device.as_ref(), raw_queue) .map_err(|_| CreateDeviceError::OutOfMemory)?; - let mut pending_writes = PendingWrites::::new(pending_encoder); + let mut pending_writes = PendingWrites::new(pending_encoder); // Create zeroed buffer used for texture clears. let zero_buffer = unsafe { @@ -297,7 +296,7 @@ impl Device { Ok(mut trace) => { trace.add(trace::Action::Init { desc: desc.clone(), - backend: A::VARIANT, + backend: adapter.raw.backend(), }); Some(trace) } @@ -321,6 +320,11 @@ impl Device { }) } + /// Returns the backend this device is using. + pub fn backend(&self) -> wgt::Backend { + self.adapter.raw.backend() + } + pub fn is_valid(&self) -> bool { self.valid.load(Ordering::Acquire) } @@ -337,7 +341,7 @@ impl Device { assert!(self.queue_to_drop.set(queue).is_ok()); } - pub(crate) fn lock_life<'a>(&'a self) -> MutexGuard<'a, LifetimeTracker> { + pub(crate) fn lock_life<'a>(&'a self) -> MutexGuard<'a, LifetimeTracker> { self.life_tracker.lock() } @@ -384,11 +388,11 @@ impl Device { } } - pub fn get_queue(&self) -> Option>> { + pub fn get_queue(&self) -> Option> { self.queue.get().as_ref()?.upgrade() } - pub fn set_queue(&self, queue: &Arc>) { + pub fn set_queue(&self, queue: &Arc) { assert!(self.queue.set(Arc::downgrade(queue)).is_ok()); } @@ -504,7 +508,7 @@ impl Device { pub(crate) fn create_buffer( self: &Arc, desc: &resource::BufferDescriptor, - ) -> Result>, resource::CreateBufferError> { + ) -> Result, resource::CreateBufferError> { self.check_is_valid()?; if desc.size > self.limits.max_buffer_size { @@ -652,7 +656,7 @@ impl Device { self: &Arc, hal_texture: Box, desc: &resource::TextureDescriptor, - ) -> Result>, resource::CreateTextureError> { + ) -> Result, resource::CreateTextureError> { let format_features = self .describe_format_features(desc.format) .map_err(|error| resource::CreateTextureError::MissingFeatures(desc.format, error))?; @@ -679,11 +683,11 @@ impl Device { pub fn create_buffer_from_hal( self: &Arc, - hal_buffer: A::Buffer, + hal_buffer: Box, desc: &resource::BufferDescriptor, - ) -> Arc> { + ) -> Arc { let buffer = Buffer { - raw: Snatchable::new(Box::new(hal_buffer)), + raw: Snatchable::new(hal_buffer), device: self.clone(), usage: desc.usage, size: desc.size, @@ -710,7 +714,7 @@ impl Device { pub(crate) fn create_texture( self: &Arc, desc: &resource::TextureDescriptor, - ) -> Result>, resource::CreateTextureError> { + ) -> Result, resource::CreateTextureError> { use resource::{CreateTextureError, TextureDimensionError}; self.check_is_valid()?; @@ -1017,9 +1021,9 @@ impl Device { pub(crate) fn create_texture_view( self: &Arc, - texture: &Arc>, + texture: &Arc, desc: &resource::TextureViewDescriptor, - ) -> Result>, resource::CreateTextureViewError> { + ) -> Result, resource::CreateTextureViewError> { self.check_is_valid()?; let snatch_guard = texture.device.snatchable_lock.read(); @@ -1323,7 +1327,7 @@ impl Device { pub(crate) fn create_sampler( self: &Arc, desc: &resource::SamplerDescriptor, - ) -> Result>, resource::CreateSamplerError> { + ) -> Result, resource::CreateSamplerError> { self.check_is_valid()?; if desc @@ -1438,7 +1442,7 @@ impl Device { self: &Arc, desc: &pipeline::ShaderModuleDescriptor<'a>, source: pipeline::ShaderModuleSource<'a>, - ) -> Result>, pipeline::CreateShaderModuleError> { + ) -> Result, pipeline::CreateShaderModuleError> { self.check_is_valid()?; let (module, source) = match source { @@ -1567,7 +1571,7 @@ impl Device { self: &Arc, desc: &pipeline::ShaderModuleDescriptor<'a>, source: &'a [u32], - ) -> Result>, pipeline::CreateShaderModuleError> { + ) -> Result, pipeline::CreateShaderModuleError> { self.check_is_valid()?; self.require_features(wgt::Features::SPIRV_SHADER_PASSTHROUGH)?; @@ -1606,7 +1610,7 @@ impl Device { pub(crate) fn create_command_encoder( self: &Arc, label: &crate::Label, - ) -> Result>, DeviceError> { + ) -> Result, DeviceError> { self.check_is_valid()?; let queue = self.get_queue().unwrap(); @@ -1626,7 +1630,7 @@ impl Device { //TODO: should this be combined with `get_introspection_bind_group_layouts` in some way? pub(crate) fn make_late_sized_buffer_groups( shader_binding_sizes: &FastHashMap, - layout: &binding_model::PipelineLayout, + layout: &binding_model::PipelineLayout, ) -> ArrayVec { // Given the shader-required binding sizes and the pipeline layout, // return the filtered list of them in the layout order, @@ -1664,7 +1668,7 @@ impl Device { label: &crate::Label, entry_map: bgl::EntryMap, origin: bgl::Origin, - ) -> Result>, binding_model::CreateBindGroupLayoutError> { + ) -> Result, binding_model::CreateBindGroupLayoutError> { #[derive(PartialEq)] enum WritableStorage { Yes, @@ -1878,13 +1882,13 @@ impl Device { pub(crate) fn create_buffer_binding<'a>( self: &Arc, - bb: &'a binding_model::ResolvedBufferBinding, + bb: &'a binding_model::ResolvedBufferBinding, binding: u32, decl: &wgt::BindGroupLayoutEntry, - used_buffer_ranges: &mut Vec>, + used_buffer_ranges: &mut Vec, dynamic_binding_info: &mut Vec, late_buffer_binding_sizes: &mut FastHashMap, - used: &mut BindGroupStates, + used: &mut BindGroupStates, limits: &wgt::Limits, snatch_guard: &'a SnatchGuard<'a>, ) -> Result, binding_model::CreateBindGroupError> @@ -2016,10 +2020,10 @@ impl Device { fn create_sampler_binding<'a>( self: &Arc, - used: &mut BindGroupStates, + used: &mut BindGroupStates, binding: u32, decl: &wgt::BindGroupLayoutEntry, - sampler: &'a Arc>, + sampler: &'a Arc, ) -> Result<&'a dyn hal::DynSampler, binding_model::CreateBindGroupError> { use crate::binding_model::CreateBindGroupError as Error; @@ -2067,9 +2071,9 @@ impl Device { self: &Arc, binding: u32, decl: &wgt::BindGroupLayoutEntry, - view: &'a Arc>, - used: &mut BindGroupStates, - used_texture_ranges: &mut Vec>, + view: &'a Arc, + used: &mut BindGroupStates, + used_texture_ranges: &mut Vec, snatch_guard: &'a SnatchGuard<'a>, ) -> Result, binding_model::CreateBindGroupError> { @@ -2109,8 +2113,8 @@ impl Device { // (not passing a duplicate) beforehand. pub(crate) fn create_bind_group( self: &Arc, - desc: binding_model::ResolvedBindGroupDescriptor, - ) -> Result>, binding_model::CreateBindGroupError> { + desc: binding_model::ResolvedBindGroupDescriptor, + ) -> Result, binding_model::CreateBindGroupError> { use crate::binding_model::{CreateBindGroupError as Error, ResolvedBindingResource as Br}; let layout = desc.layout; @@ -2357,7 +2361,7 @@ impl Device { self: &Arc, binding: u32, decl: &wgt::BindGroupLayoutEntry, - view: &TextureView, + view: &TextureView, expected: &'static str, ) -> Result<(wgt::TextureUsages, hal::TextureUses), binding_model::CreateBindGroupError> { use crate::binding_model::CreateBindGroupError as Error; @@ -2486,9 +2490,8 @@ impl Device { pub(crate) fn create_pipeline_layout( self: &Arc, - desc: &binding_model::ResolvedPipelineLayoutDescriptor, - ) -> Result>, binding_model::CreatePipelineLayoutError> - { + desc: &binding_model::ResolvedPipelineLayoutDescriptor, + ) -> Result, binding_model::CreatePipelineLayoutError> { use crate::binding_model::CreatePipelineLayoutError as Error; self.check_is_valid()?; @@ -2594,7 +2597,7 @@ impl Device { pub(crate) fn derive_pipeline_layout( self: &Arc, mut derived_group_layouts: ArrayVec, - ) -> Result>, pipeline::ImplicitLayoutError> { + ) -> Result, pipeline::ImplicitLayoutError> { while derived_group_layouts .last() .map_or(false, |map| map.is_empty()) @@ -2639,8 +2642,8 @@ impl Device { pub(crate) fn create_compute_pipeline( self: &Arc, - desc: pipeline::ResolvedComputePipelineDescriptor, - ) -> Result>, pipeline::CreateComputePipelineError> { + desc: pipeline::ResolvedComputePipelineDescriptor, + ) -> Result, pipeline::CreateComputePipelineError> { self.check_is_valid()?; self.require_downlevel_flags(wgt::DownlevelFlags::COMPUTE_SHADERS)?; @@ -2772,8 +2775,8 @@ impl Device { pub(crate) fn create_render_pipeline( self: &Arc, - desc: pipeline::ResolvedRenderPipelineDescriptor, - ) -> Result>, pipeline::CreateRenderPipelineError> { + desc: pipeline::ResolvedRenderPipelineDescriptor, + ) -> Result, pipeline::CreateRenderPipelineError> { use wgt::TextureFormatFeatureFlags as Tfff; self.check_is_valid()?; @@ -3400,7 +3403,7 @@ impl Device { pub unsafe fn create_pipeline_cache( self: &Arc, desc: &pipeline::PipelineCacheDescriptor, - ) -> Result>, pipeline::CreatePipelineCacheError> { + ) -> Result, pipeline::CreatePipelineCacheError> { use crate::pipeline_cache; self.check_is_valid()?; @@ -3509,7 +3512,7 @@ impl Device { pub(crate) fn create_query_set( self: &Arc, desc: &resource::QuerySetDescriptor, - ) -> Result>, resource::CreateQuerySetError> { + ) -> Result, resource::CreateQuerySetError> { use resource::CreateQuerySetError as Error; self.check_is_valid()?; @@ -3605,7 +3608,7 @@ impl Device { } } - pub(crate) fn new_usage_scope(&self) -> UsageScope<'_, A> { + pub(crate) fn new_usage_scope(&self) -> UsageScope<'_> { UsageScope::new_pooled(&self.usage_scopes, &self.tracker_indices) } @@ -3618,8 +3621,8 @@ impl Device { } } -impl Device { - pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer) { +impl Device { + pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer) { let mut baked = cmd_buf.extract_baked_commands(); unsafe { baked.encoder.reset_all(baked.list); @@ -3656,6 +3659,6 @@ impl Device { } } -crate::impl_resource_type_generic!(Device); +crate::impl_resource_type!(Device); crate::impl_labeled!(Device); -crate::impl_storage_item_generic!(Device); +crate::impl_storage_item!(Device); diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index e4708fd4dc..4d79a81e3b 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -1,10 +1,6 @@ -use std::collections::HashMap; - -use wgt::Backend; - use crate::{ hal_api::HalApi, - hub::{HubReport, Hubs}, + hub::{Hub, HubReport}, instance::{Instance, Surface}, registry::{Registry, RegistryReport}, resource_log, @@ -13,22 +9,22 @@ use crate::{ #[derive(Debug, PartialEq, Eq)] pub struct GlobalReport { pub surfaces: RegistryReport, - pub report_per_backend: HashMap, + pub hub: HubReport, } impl GlobalReport { pub fn surfaces(&self) -> &RegistryReport { &self.surfaces } - pub fn hub_report(&self, backend: Backend) -> &HubReport { - self.report_per_backend.get(&backend).unwrap() + pub fn hub_report(&self) -> &HubReport { + &self.hub } } pub struct Global { pub instance: Instance, pub(crate) surfaces: Registry, - pub(crate) hubs: Hubs, + pub(crate) hub: Hub, } impl Global { @@ -36,8 +32,8 @@ impl Global { profiling::scope!("Global::new"); Self { instance: Instance::new(name, instance_desc), - surfaces: Registry::without_backend(), - hubs: Hubs::new(), + surfaces: Registry::new(), + hub: Hub::new(), } } @@ -54,8 +50,8 @@ impl Global { instance_per_backend: std::iter::once((A::VARIANT, dyn_instance)).collect(), ..Default::default() }, - surfaces: Registry::without_backend(), - hubs: Hubs::new(), + surfaces: Registry::new(), + hub: Hub::new(), } } @@ -79,47 +75,15 @@ impl Global { profiling::scope!("Global::new"); Self { instance, - surfaces: Registry::without_backend(), - hubs: Hubs::new(), + surfaces: Registry::new(), + hub: Hub::new(), } } pub fn generate_report(&self) -> GlobalReport { - let mut report_per_backend = HashMap::default(); - let instance_per_backend = &self.instance.instance_per_backend; - - #[cfg(vulkan)] - if instance_per_backend - .iter() - .any(|(backend, _)| backend == &Backend::Vulkan) - { - report_per_backend.insert(Backend::Vulkan, self.hubs.vulkan.generate_report()); - }; - #[cfg(metal)] - if instance_per_backend - .iter() - .any(|(backend, _)| backend == &Backend::Metal) - { - report_per_backend.insert(Backend::Metal, self.hubs.metal.generate_report()); - }; - #[cfg(dx12)] - if instance_per_backend - .iter() - .any(|(backend, _)| backend == &Backend::Dx12) - { - report_per_backend.insert(Backend::Dx12, self.hubs.dx12.generate_report()); - }; - #[cfg(gles)] - if instance_per_backend - .iter() - .any(|(backend, _)| backend == &Backend::Gl) - { - report_per_backend.insert(Backend::Gl, self.hubs.gl.generate_report()); - }; - GlobalReport { surfaces: self.surfaces.generate_report(), - report_per_backend, + hub: self.hub.generate_report(), } } } @@ -130,23 +94,8 @@ impl Drop for Global { resource_log!("Global::drop"); let mut surfaces_locked = self.surfaces.write(); - // destroy hubs before the instance gets dropped - #[cfg(vulkan)] - { - self.hubs.vulkan.clear(&surfaces_locked); - } - #[cfg(metal)] - { - self.hubs.metal.clear(&surfaces_locked); - } - #[cfg(dx12)] - { - self.hubs.dx12.clear(&surfaces_locked); - } - #[cfg(gles)] - { - self.hubs.gl.clear(&surfaces_locked); - } + // destroy hub before the instance gets dropped + self.hub.clear(&surfaces_locked); surfaces_locked.map.clear(); } diff --git a/wgpu-core/src/hal_api.rs b/wgpu-core/src/hal_api.rs index ebd09ffc73..b41847b8d5 100644 --- a/wgpu-core/src/hal_api.rs +++ b/wgpu-core/src/hal_api.rs @@ -1,53 +1,29 @@ use wgt::{Backend, WasmNotSendSync}; -use crate::{global::Global, hub::Hub}; - pub trait HalApi: hal::Api + 'static + WasmNotSendSync { const VARIANT: Backend; - - fn hub(global: &Global) -> &Hub; } impl HalApi for hal::api::Empty { const VARIANT: Backend = Backend::Empty; - - fn hub(_: &Global) -> &Hub { - unimplemented!("called empty api") - } } #[cfg(vulkan)] impl HalApi for hal::api::Vulkan { const VARIANT: Backend = Backend::Vulkan; - - fn hub(global: &Global) -> &Hub { - &global.hubs.vulkan - } } #[cfg(metal)] impl HalApi for hal::api::Metal { const VARIANT: Backend = Backend::Metal; - - fn hub(global: &Global) -> &Hub { - &global.hubs.metal - } } #[cfg(dx12)] impl HalApi for hal::api::Dx12 { const VARIANT: Backend = Backend::Dx12; - - fn hub(global: &Global) -> &Hub { - &global.hubs.dx12 - } } #[cfg(gles)] impl HalApi for hal::api::Gles { const VARIANT: Backend = Backend::Gl; - - fn hub(global: &Global) -> &Hub { - &global.hubs.gl - } } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index a4d04f3f7c..cfdca16832 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -108,7 +108,6 @@ use crate::{ binding_model::{BindGroup, BindGroupLayout, PipelineLayout}, command::{CommandBuffer, RenderBundle}, device::{queue::Queue, Device}, - hal_api::HalApi, instance::{Adapter, Surface}, pipeline::{ComputePipeline, PipelineCache, RenderPipeline, ShaderModule}, registry::{Registry, RegistryReport}, @@ -145,10 +144,7 @@ impl HubReport { } #[allow(rustdoc::private_intra_doc_links)] -/// All the resources for a particular backend in a [`crate::global::Global`]. -/// -/// To obtain `global`'s `Hub` for some [`HalApi`] backend type `A`, -/// call [`A::hub(global)`]. +/// All the resources tracked by a [`crate::global::Global`]. /// /// ## Locking /// @@ -169,48 +165,48 @@ impl HubReport { /// /// /// [`A::hub(global)`]: HalApi::hub -pub struct Hub { +pub struct Hub { pub(crate) adapters: Registry, - pub(crate) devices: Registry>, - pub(crate) queues: Registry>, - pub(crate) pipeline_layouts: Registry>, - pub(crate) shader_modules: Registry>, - pub(crate) bind_group_layouts: Registry>, - pub(crate) bind_groups: Registry>, - pub(crate) command_buffers: Registry>, - pub(crate) render_bundles: Registry>, - pub(crate) render_pipelines: Registry>, - pub(crate) compute_pipelines: Registry>, - pub(crate) pipeline_caches: Registry>, - pub(crate) query_sets: Registry>, - pub(crate) buffers: Registry>, - pub(crate) staging_buffers: Registry>, - pub(crate) textures: Registry>, - pub(crate) texture_views: Registry>, - pub(crate) samplers: Registry>, + pub(crate) devices: Registry, + pub(crate) queues: Registry, + pub(crate) pipeline_layouts: Registry, + pub(crate) shader_modules: Registry, + pub(crate) bind_group_layouts: Registry, + pub(crate) bind_groups: Registry, + pub(crate) command_buffers: Registry, + pub(crate) render_bundles: Registry, + pub(crate) render_pipelines: Registry, + pub(crate) compute_pipelines: Registry, + pub(crate) pipeline_caches: Registry, + pub(crate) query_sets: Registry, + pub(crate) buffers: Registry, + pub(crate) staging_buffers: Registry, + pub(crate) textures: Registry, + pub(crate) texture_views: Registry, + pub(crate) samplers: Registry, } -impl Hub { - fn new() -> Self { +impl Hub { + pub(crate) fn new() -> Self { Self { - adapters: Registry::new(A::VARIANT), - devices: Registry::new(A::VARIANT), - queues: Registry::new(A::VARIANT), - pipeline_layouts: Registry::new(A::VARIANT), - shader_modules: Registry::new(A::VARIANT), - bind_group_layouts: Registry::new(A::VARIANT), - bind_groups: Registry::new(A::VARIANT), - command_buffers: Registry::new(A::VARIANT), - render_bundles: Registry::new(A::VARIANT), - render_pipelines: Registry::new(A::VARIANT), - compute_pipelines: Registry::new(A::VARIANT), - pipeline_caches: Registry::new(A::VARIANT), - query_sets: Registry::new(A::VARIANT), - buffers: Registry::new(A::VARIANT), - staging_buffers: Registry::new(A::VARIANT), - textures: Registry::new(A::VARIANT), - texture_views: Registry::new(A::VARIANT), - samplers: Registry::new(A::VARIANT), + adapters: Registry::new(), + devices: Registry::new(), + queues: Registry::new(), + pipeline_layouts: Registry::new(), + shader_modules: Registry::new(), + bind_group_layouts: Registry::new(), + bind_groups: Registry::new(), + command_buffers: Registry::new(), + render_bundles: Registry::new(), + render_pipelines: Registry::new(), + compute_pipelines: Registry::new(), + pipeline_caches: Registry::new(), + query_sets: Registry::new(), + buffers: Registry::new(), + staging_buffers: Registry::new(), + textures: Registry::new(), + texture_views: Registry::new(), + samplers: Registry::new(), } } @@ -239,11 +235,9 @@ impl Hub { for element in surface_guard.map.iter() { if let Element::Occupied(ref surface, _epoch) = *element { if let Some(ref mut present) = surface.presentation.lock().take() { - if let Some(device) = present.device.downcast_ref::() { - let suf = surface.raw(A::VARIANT); - unsafe { - suf.unwrap().unconfigure(device.raw()); - } + let suf = surface.raw(present.device.backend()); + unsafe { + suf.unwrap().unconfigure(present.device.raw()); } } } @@ -278,33 +272,3 @@ impl Hub { } } } - -pub struct Hubs { - #[cfg(vulkan)] - pub(crate) vulkan: Hub, - #[cfg(metal)] - pub(crate) metal: Hub, - #[cfg(dx12)] - pub(crate) dx12: Hub, - #[cfg(gles)] - pub(crate) gl: Hub, - #[cfg(all(not(vulkan), not(metal), not(dx12), not(gles)))] - pub(crate) empty: Hub, -} - -impl Hubs { - pub(crate) fn new() -> Self { - Self { - #[cfg(vulkan)] - vulkan: Hub::new(), - #[cfg(metal)] - metal: Hub::new(), - #[cfg(dx12)] - dx12: Hub::new(), - #[cfg(gles)] - gl: Hub::new(), - #[cfg(all(not(vulkan), not(metal), not(dx12), not(gles)))] - empty: Hub::new(), - } - } -} diff --git a/wgpu-core/src/init_tracker/buffer.rs b/wgpu-core/src/init_tracker/buffer.rs index 2c0fa8d372..ee8e99aa22 100644 --- a/wgpu-core/src/init_tracker/buffer.rs +++ b/wgpu-core/src/init_tracker/buffer.rs @@ -1,10 +1,10 @@ use super::{InitTracker, MemoryInitKind}; -use crate::{hal_api::HalApi, resource::Buffer}; +use crate::resource::Buffer; use std::{ops::Range, sync::Arc}; #[derive(Debug, Clone)] -pub(crate) struct BufferInitTrackerAction { - pub buffer: Arc>, +pub(crate) struct BufferInitTrackerAction { + pub buffer: Arc, pub range: Range, pub kind: MemoryInitKind, } @@ -14,21 +14,21 @@ pub(crate) type BufferInitTracker = InitTracker; impl BufferInitTracker { /// Checks if an action has/requires any effect on the initialization status /// and shrinks its range if possible. - pub(crate) fn check_action( + pub(crate) fn check_action( &self, - action: &BufferInitTrackerAction, - ) -> Option> { + action: &BufferInitTrackerAction, + ) -> Option { self.create_action(&action.buffer, action.range.clone(), action.kind) } /// Creates an action if it would have any effect on the initialization /// status and shrinks the range if possible. - pub(crate) fn create_action( + pub(crate) fn create_action( &self, - buffer: &Arc>, + buffer: &Arc, query_range: Range, kind: MemoryInitKind, - ) -> Option> { + ) -> Option { self.check(query_range) .map(|range| BufferInitTrackerAction { buffer: buffer.clone(), diff --git a/wgpu-core/src/init_tracker/texture.rs b/wgpu-core/src/init_tracker/texture.rs index 4785b52229..4bf7278f21 100644 --- a/wgpu-core/src/init_tracker/texture.rs +++ b/wgpu-core/src/init_tracker/texture.rs @@ -1,5 +1,5 @@ use super::{InitTracker, MemoryInitKind}; -use crate::{hal_api::HalApi, resource::Texture, track::TextureSelector}; +use crate::{resource::Texture, track::TextureSelector}; use arrayvec::ArrayVec; use std::{ops::Range, sync::Arc}; @@ -35,8 +35,8 @@ impl From for TextureInitRange { } #[derive(Debug, Clone)] -pub(crate) struct TextureInitTrackerAction { - pub(crate) texture: Arc>, +pub(crate) struct TextureInitTrackerAction { + pub(crate) texture: Arc, pub(crate) range: TextureInitRange, pub(crate) kind: MemoryInitKind, } @@ -57,10 +57,10 @@ impl TextureInitTracker { } } - pub(crate) fn check_action( + pub(crate) fn check_action( &self, - action: &TextureInitTrackerAction, - ) -> Option> { + action: &TextureInitTrackerAction, + ) -> Option { let mut mip_range_start = usize::MAX; let mut mip_range_end = usize::MIN; let mut layer_range_start = u32::MAX; diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 9c0a5fd3bb..8c7585be99 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use std::{borrow::Cow, collections::HashMap}; +use crate::hub::Hub; use crate::{ api_log, device::{queue::Queue, resource::Device, DeviceDescriptor}, @@ -262,13 +263,13 @@ impl Adapter { } #[allow(clippy::type_complexity)] - fn create_device_and_queue_from_hal( + fn create_device_and_queue_from_hal( self: &Arc, hal_device: hal::DynOpenDevice, desc: &DeviceDescriptor, instance_flags: wgt::InstanceFlags, trace_path: Option<&std::path::Path>, - ) -> Result<(Arc>, Arc>), RequestDeviceError> { + ) -> Result<(Arc, Arc), RequestDeviceError> { api_log!("Adapter::create_device"); if let Ok(device) = Device::new( @@ -288,12 +289,12 @@ impl Adapter { } #[allow(clippy::type_complexity)] - fn create_device_and_queue( + fn create_device_and_queue( self: &Arc, desc: &DeviceDescriptor, instance_flags: wgt::InstanceFlags, trace_path: Option<&std::path::Path>, - ) -> Result<(Arc>, Arc>), RequestDeviceError> { + ) -> Result<(Arc, Arc), RequestDeviceError> { // Verify all features were exposed by the adapter if !self.raw.features.contains(desc.required_features) { return Err(RequestDeviceError::UnsupportedFeature( @@ -302,7 +303,7 @@ impl Adapter { } let caps = &self.raw.capabilities; - if Backends::PRIMARY.contains(Backends::from(A::VARIANT)) + if Backends::PRIMARY.contains(Backends::from(self.raw.backend())) && !caps.downlevel.is_webgpu_compliant() { let missing_flags = wgt::DownlevelFlags::compliant() - caps.downlevel.flags; @@ -495,7 +496,10 @@ impl Global { }; #[allow(clippy::arc_with_non_send_sync)] - let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); + let id = self + .surfaces + .prepare(wgt::Backend::Empty, id_in) // No specific backend for Surface, since it's not specific. + .assign(Arc::new(surface)); Ok(id) } } @@ -538,7 +542,10 @@ impl Global { surface_per_backend: std::iter::once((Backend::Metal, raw_surface)).collect(), }; - let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); + let id = self + .surfaces + .prepare(Backend::Metal, id_in) + .assign(Arc::new(surface)); Ok(id) } @@ -560,7 +567,10 @@ impl Global { surface_per_backend: std::iter::once((Backend::Dx12, surface)).collect(), }; - let id = self.surfaces.prepare(id_in).assign(Arc::new(surface)); + let id = self + .surfaces + .prepare(Backend::Dx12, id_in) + .assign(Arc::new(surface)); Ok(id) } @@ -614,83 +624,65 @@ impl Global { api_log!("Surface::drop {id:?}"); - fn unconfigure(surface: &Surface, present: &Presentation) { - if let Some(surface) = surface.raw(A::VARIANT) { - if let Some(device) = present.device.downcast_ref::() { - unsafe { surface.unconfigure(device.raw()) }; - } - } - } - let surface = self.surfaces.unregister(id); let surface = Arc::into_inner(surface.unwrap()) .expect("Surface cannot be destroyed because is still in use"); if let Some(present) = surface.presentation.lock().take() { - // TODO(#5124): Becomes a loop once we use Arc - #[cfg(vulkan)] - unconfigure::(&surface, &present); - #[cfg(metal)] - unconfigure::(&surface, &present); - #[cfg(dx12)] - unconfigure::(&surface, &present); - #[cfg(gles)] - unconfigure::(&surface, &present); + for (&backend, surface) in &surface.surface_per_backend { + if backend == present.device.backend() { + unsafe { surface.unconfigure(present.device.raw()) }; + } + } } drop(surface) } - fn enumerate( - &self, - inputs: &AdapterInputs, - list: &mut Vec, - ) { - let inst = match self - .instance - .instance_per_backend - .iter() - .find(|(backend, _)| backend == &A::VARIANT) - { - Some((_, inst)) => inst.as_ref(), - None => return, - }; - let id_backend = match inputs.find(A::VARIANT) { - Some(id) => id, - None => return, - }; - - profiling::scope!("enumerating", &*format!("{:?}", backend)); - let hub: &crate::hub::Hub = HalApi::hub(self); - - let hal_adapters = unsafe { inst.enumerate_adapters(None) }; - for raw in hal_adapters { - let adapter = Adapter::new(raw); - log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info); - let id = hub.adapters.prepare(id_backend).assign(Arc::new(adapter)); - list.push(id); - } - } - pub fn enumerate_adapters(&self, inputs: AdapterInputs) -> Vec { profiling::scope!("Instance::enumerate_adapters"); api_log!("Instance::enumerate_adapters"); - let mut adapters = Vec::new(); + fn enumerate( + hub: &Hub, + backend: Backend, + instance: &dyn hal::DynInstance, + inputs: &AdapterInputs, + list: &mut Vec, + ) { + let Some(id_backend) = inputs.find(backend) else { + return; + }; - #[cfg(vulkan)] - self.enumerate::(&inputs, &mut adapters); - #[cfg(metal)] - self.enumerate::(&inputs, &mut adapters); - #[cfg(dx12)] - self.enumerate::(&inputs, &mut adapters); - #[cfg(gles)] - self.enumerate::(&inputs, &mut adapters); + profiling::scope!("enumerating", &*format!("{:?}", backend)); + + let hal_adapters = unsafe { instance.enumerate_adapters(None) }; + for raw in hal_adapters { + let adapter = Adapter::new(raw); + log::info!("Adapter {:?}", adapter.raw.info); + let id = hub + .adapters + .prepare(backend, id_backend) + .assign(Arc::new(adapter)); + list.push(id); + } + } + let mut adapters = Vec::new(); + for (backend, instance) in &self.instance.instance_per_backend { + enumerate( + &self.hub, + *backend, + instance.as_ref(), + &inputs, + &mut adapters, + ); + } adapters } - fn select( + fn select( &self, + backend: Backend, selected: &mut usize, new_id: Option, mut list: Vec, @@ -703,9 +695,10 @@ impl Global { None => { let adapter = Adapter::new(list.swap_remove(*selected)); log::info!("Adapter {:?}", adapter.raw.info); - let id = A::hub(self) + let id = self + .hub .adapters - .prepare(new_id) + .prepare(backend, new_id) .assign(Arc::new(adapter)); Some(id) } @@ -848,19 +841,19 @@ impl Global { let mut selected = preferred_gpu.unwrap_or(0); #[cfg(vulkan)] - if let Some(id) = self.select::(&mut selected, id_vulkan, adapters_vk) { + if let Some(id) = self.select(Backend::Vulkan, &mut selected, id_vulkan, adapters_vk) { return Ok(id); } #[cfg(metal)] - if let Some(id) = self.select::(&mut selected, id_metal, adapters_metal) { + if let Some(id) = self.select(Backend::Metal, &mut selected, id_metal, adapters_metal) { return Ok(id); } #[cfg(dx12)] - if let Some(id) = self.select::(&mut selected, id_dx12, adapters_dx12) { + if let Some(id) = self.select(Backend::Dx12, &mut selected, id_dx12, adapters_dx12) { return Ok(id); } #[cfg(gles)] - if let Some(id) = self.select::(&mut selected, id_gl, adapters_gl) { + if let Some(id) = self.select(Backend::Gl, &mut selected, id_gl, adapters_gl) { return Ok(id); } let _ = selected; @@ -872,113 +865,92 @@ impl Global { /// # Safety /// /// `hal_adapter` must be created from this global internal instance handle. - pub unsafe fn create_adapter_from_hal( + pub unsafe fn create_adapter_from_hal( &self, hal_adapter: hal::DynExposedAdapter, input: Option, ) -> AdapterId { profiling::scope!("Instance::create_adapter_from_hal"); - let fid = A::hub(self).adapters.prepare(input); - - let id = match A::VARIANT { - #[cfg(vulkan)] - Backend::Vulkan => fid.assign(Arc::new(Adapter::new(hal_adapter))), - #[cfg(metal)] - Backend::Metal => fid.assign(Arc::new(Adapter::new(hal_adapter))), - #[cfg(dx12)] - Backend::Dx12 => fid.assign(Arc::new(Adapter::new(hal_adapter))), - #[cfg(gles)] - Backend::Gl => fid.assign(Arc::new(Adapter::new(hal_adapter))), - _ => unreachable!(), - }; + let fid = self.hub.adapters.prepare(hal_adapter.backend(), input); + let id = fid.assign(Arc::new(Adapter::new(hal_adapter))); + resource_log!("Created Adapter {:?}", id); id } - pub fn adapter_get_info( + pub fn adapter_get_info( &self, adapter_id: AdapterId, ) -> Result { - let hub = A::hub(self); - - hub.adapters + self.hub + .adapters .get(adapter_id) .map(|adapter| adapter.raw.info.clone()) .map_err(|_| InvalidAdapter) } - pub fn adapter_get_texture_format_features( + pub fn adapter_get_texture_format_features( &self, adapter_id: AdapterId, format: wgt::TextureFormat, ) -> Result { - let hub = A::hub(self); - - hub.adapters + self.hub + .adapters .get(adapter_id) .map(|adapter| adapter.get_texture_format_features(format)) .map_err(|_| InvalidAdapter) } - pub fn adapter_features( - &self, - adapter_id: AdapterId, - ) -> Result { - let hub = A::hub(self); - - hub.adapters + pub fn adapter_features(&self, adapter_id: AdapterId) -> Result { + self.hub + .adapters .get(adapter_id) .map(|adapter| adapter.raw.features) .map_err(|_| InvalidAdapter) } - pub fn adapter_limits( - &self, - adapter_id: AdapterId, - ) -> Result { - let hub = A::hub(self); - - hub.adapters + pub fn adapter_limits(&self, adapter_id: AdapterId) -> Result { + self.hub + .adapters .get(adapter_id) .map(|adapter| adapter.raw.capabilities.limits.clone()) .map_err(|_| InvalidAdapter) } - pub fn adapter_downlevel_capabilities( + pub fn adapter_downlevel_capabilities( &self, adapter_id: AdapterId, ) -> Result { - let hub = A::hub(self); - - hub.adapters + self.hub + .adapters .get(adapter_id) .map(|adapter| adapter.raw.capabilities.downlevel.clone()) .map_err(|_| InvalidAdapter) } - pub fn adapter_get_presentation_timestamp( + pub fn adapter_get_presentation_timestamp( &self, adapter_id: AdapterId, ) -> Result { - let hub = A::hub(self); + let hub = &self.hub; let adapter = hub.adapters.get(adapter_id).map_err(|_| InvalidAdapter)?; Ok(unsafe { adapter.raw.adapter.get_presentation_timestamp() }) } - pub fn adapter_drop(&self, adapter_id: AdapterId) { + pub fn adapter_drop(&self, adapter_id: AdapterId) { profiling::scope!("Adapter::drop"); api_log!("Adapter::drop {adapter_id:?}"); - let hub = A::hub(self); + let hub = &self.hub; hub.adapters.unregister(adapter_id); } } impl Global { - pub fn adapter_request_device( + pub fn adapter_request_device( &self, adapter_id: AdapterId, desc: &DeviceDescriptor, @@ -989,12 +961,12 @@ impl Global { profiling::scope!("Adapter::request_device"); api_log!("Adapter::request_device"); - let hub = A::hub(self); - let device_fid = hub.devices.prepare(device_id_in); - let queue_fid = hub.queues.prepare(queue_id_in); + let backend = adapter_id.backend(); + let device_fid = self.hub.devices.prepare(backend, device_id_in); + let queue_fid = self.hub.queues.prepare(backend, queue_id_in); let error = 'error: { - let adapter = match hub.adapters.get(adapter_id) { + let adapter = match self.hub.adapters.get(adapter_id) { Ok(adapter) => adapter, Err(_) => break 'error RequestDeviceError::InvalidAdapter, }; @@ -1022,7 +994,7 @@ impl Global { /// /// - `hal_device` must be created from `adapter_id` or its internal handle. /// - `desc` must be a subset of `hal_device` features and limits. - pub unsafe fn create_device_from_hal( + pub unsafe fn create_device_from_hal( &self, adapter_id: AdapterId, hal_device: hal::DynOpenDevice, @@ -1033,12 +1005,12 @@ impl Global { ) -> (DeviceId, QueueId, Option) { profiling::scope!("Global::create_device_from_hal"); - let hub = A::hub(self); - let devices_fid = hub.devices.prepare(device_id_in); - let queues_fid = hub.queues.prepare(queue_id_in); + let backend = adapter_id.backend(); + let devices_fid = self.hub.devices.prepare(backend, device_id_in); + let queues_fid = self.hub.queues.prepare(backend, queue_id_in); let error = 'error: { - let adapter = match hub.adapters.get(adapter_id) { + let adapter = match self.hub.adapters.get(adapter_id) { Ok(adapter) => adapter, Err(_) => break 'error RequestDeviceError::InvalidAdapter, }; diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 351916002f..179664490c 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -290,6 +290,8 @@ define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all( /// [`wgpu_types::Backend`]: wgt::Backend /// [`wgpu_core::global::Global`]: crate::global::Global /// [`Id`]: id::Id +// +// TODO(#5124): Remove this altogether. #[macro_export] macro_rules! gfx_select { // Simple two-component expression, like `self.0.method(..)`. @@ -303,14 +305,7 @@ macro_rules! gfx_select { }; ($id:expr => {$($c:tt)*}, $method:ident $params:tt) => { - match $id.backend() { - wgt::Backend::Vulkan => $crate::gfx_if_vulkan!($($c)*.$method::<$crate::api::Vulkan> $params), - wgt::Backend::Metal => $crate::gfx_if_metal!($($c)*.$method::<$crate::api::Metal> $params), - wgt::Backend::Dx12 => $crate::gfx_if_dx12!($($c)*.$method::<$crate::api::Dx12> $params), - wgt::Backend::Gl => $crate::gfx_if_gles!($($c)*.$method::<$crate::api::Gles> $params), - wgt::Backend::Empty => $crate::gfx_if_empty!($($c)*.$method::<$crate::api::Empty> $params), - other => panic!("Unexpected backend {:?}", other), - } + $($c)*.$method $params }; } diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 7e58962dbc..db1c1ba76a 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -3,7 +3,6 @@ use crate::{ binding_model::{CreateBindGroupLayoutError, CreatePipelineLayoutError, PipelineLayout}, command::ColorAttachmentError, device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext}, - hal_api::HalApi, id::{PipelineCacheId, PipelineLayoutId, ShaderModuleId}, resource::{Labeled, TrackingData}, resource_log, validation, Label, @@ -46,15 +45,15 @@ pub struct ShaderModuleDescriptor<'a> { } #[derive(Debug)] -pub struct ShaderModule { +pub struct ShaderModule { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, pub(crate) interface: Option, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, } -impl Drop for ShaderModule { +impl Drop for ShaderModule { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -65,12 +64,12 @@ impl Drop for ShaderModule { } } -crate::impl_resource_type_generic!(ShaderModule); +crate::impl_resource_type!(ShaderModule); crate::impl_labeled!(ShaderModule); crate::impl_parent_device!(ShaderModule); -crate::impl_storage_item_generic!(ShaderModule); +crate::impl_storage_item!(ShaderModule); -impl ShaderModule { +impl ShaderModule { pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule { self.raw.as_ref() } @@ -150,9 +149,9 @@ pub struct ProgrammableStageDescriptor<'a> { /// Describes a programmable pipeline stage. #[derive(Clone, Debug)] -pub struct ResolvedProgrammableStageDescriptor<'a, A: HalApi> { +pub struct ResolvedProgrammableStageDescriptor<'a> { /// The compiled shader module for this stage. - pub module: Arc>, + pub module: Arc, /// The name of the entry point in the compiled shader. The name is selected using the /// following logic: /// @@ -208,14 +207,14 @@ pub struct ComputePipelineDescriptor<'a> { /// Describes a compute pipeline. #[derive(Clone, Debug)] -pub struct ResolvedComputePipelineDescriptor<'a, A: HalApi> { +pub struct ResolvedComputePipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. - pub layout: Option>>, + pub layout: Option>, /// The compiled compute stage and its entry point. - pub stage: ResolvedProgrammableStageDescriptor<'a, A>, + pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The pipeline cache to use when creating this pipeline. - pub cache: Option>>, + pub cache: Option>, } #[derive(Clone, Debug, Error)] @@ -240,18 +239,18 @@ pub enum CreateComputePipelineError { } #[derive(Debug)] -pub struct ComputePipeline { +pub struct ComputePipeline { pub(crate) raw: ManuallyDrop>, - pub(crate) layout: Arc>, - pub(crate) device: Arc>, - pub(crate) _shader_module: Arc>, + pub(crate) layout: Arc, + pub(crate) device: Arc, + pub(crate) _shader_module: Arc, pub(crate) late_sized_buffer_groups: ArrayVec, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, } -impl Drop for ComputePipeline { +impl Drop for ComputePipeline { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -262,13 +261,13 @@ impl Drop for ComputePipeline { } } -crate::impl_resource_type_generic!(ComputePipeline); +crate::impl_resource_type!(ComputePipeline); crate::impl_labeled!(ComputePipeline); crate::impl_parent_device!(ComputePipeline); -crate::impl_storage_item_generic!(ComputePipeline); +crate::impl_storage_item!(ComputePipeline); crate::impl_trackable!(ComputePipeline); -impl ComputePipeline { +impl ComputePipeline { pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline { self.raw.as_ref() } @@ -298,14 +297,14 @@ impl From for CreatePipelineCacheError { } #[derive(Debug)] -pub struct PipelineCache { +pub struct PipelineCache { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, } -impl Drop for PipelineCache { +impl Drop for PipelineCache { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -316,12 +315,12 @@ impl Drop for PipelineCache { } } -crate::impl_resource_type_generic!(PipelineCache); +crate::impl_resource_type!(PipelineCache); crate::impl_labeled!(PipelineCache); crate::impl_parent_device!(PipelineCache); -crate::impl_storage_item_generic!(PipelineCache); +crate::impl_storage_item!(PipelineCache); -impl PipelineCache { +impl PipelineCache { pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache { self.raw.as_ref() } @@ -352,9 +351,9 @@ pub struct VertexState<'a> { /// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] -pub struct ResolvedVertexState<'a, A: HalApi> { +pub struct ResolvedVertexState<'a> { /// The compiled vertex stage and its entry point. - pub stage: ResolvedProgrammableStageDescriptor<'a, A>, + pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The format of any vertex buffers used with this pipeline. pub buffers: Cow<'a, [VertexBufferLayout<'a>]>, } @@ -371,9 +370,9 @@ pub struct FragmentState<'a> { /// Describes fragment processing in a render pipeline. #[derive(Clone, Debug)] -pub struct ResolvedFragmentState<'a, A: HalApi> { +pub struct ResolvedFragmentState<'a> { /// The compiled fragment stage and its entry point. - pub stage: ResolvedProgrammableStageDescriptor<'a, A>, + pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The effect of draw calls on the color aspect of the output target. pub targets: Cow<'a, [Option]>, } @@ -407,12 +406,12 @@ pub struct RenderPipelineDescriptor<'a> { /// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] -pub struct ResolvedRenderPipelineDescriptor<'a, A: HalApi> { +pub struct ResolvedRenderPipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. - pub layout: Option>>, + pub layout: Option>, /// The vertex processing state for this pipeline. - pub vertex: ResolvedVertexState<'a, A>, + pub vertex: ResolvedVertexState<'a>, /// The properties of the pipeline at the primitive assembly and rasterization level. pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. @@ -420,12 +419,12 @@ pub struct ResolvedRenderPipelineDescriptor<'a, A: HalApi> { /// The multi-sampling properties of the pipeline. pub multisample: wgt::MultisampleState, /// The fragment processing state for this pipeline. - pub fragment: Option>, + pub fragment: Option>, /// If the pipeline will be used with a multiview render pass, this indicates how many array /// layers the attachments will have. pub multiview: Option, /// The pipeline cache to use when creating this pipeline. - pub cache: Option>>, + pub cache: Option>, } #[derive(Clone, Debug)] @@ -588,12 +587,11 @@ impl Default for VertexStep { } #[derive(Debug)] -pub struct RenderPipeline { +pub struct RenderPipeline { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, - pub(crate) layout: Arc>, - pub(crate) _shader_modules: - ArrayVec>, { hal::MAX_CONCURRENT_SHADER_STAGES }>, + pub(crate) device: Arc, + pub(crate) layout: Arc, + pub(crate) _shader_modules: ArrayVec, { hal::MAX_CONCURRENT_SHADER_STAGES }>, pub(crate) pass_context: RenderPassContext, pub(crate) flags: PipelineFlags, pub(crate) strip_index_format: Option, @@ -604,7 +602,7 @@ pub struct RenderPipeline { pub(crate) tracking_data: TrackingData, } -impl Drop for RenderPipeline { +impl Drop for RenderPipeline { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -615,13 +613,13 @@ impl Drop for RenderPipeline { } } -crate::impl_resource_type_generic!(RenderPipeline); +crate::impl_resource_type!(RenderPipeline); crate::impl_labeled!(RenderPipeline); crate::impl_parent_device!(RenderPipeline); -crate::impl_storage_item_generic!(RenderPipeline); +crate::impl_storage_item!(RenderPipeline); crate::impl_trackable!(RenderPipeline); -impl RenderPipeline { +impl RenderPipeline { pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline { self.raw.as_ref() } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 4ac286b497..697156b35f 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -15,10 +15,8 @@ use std::{mem::ManuallyDrop, sync::Arc}; use crate::device::trace::Action; use crate::{ conv, - device::any_device::AnyDevice, - device::{DeviceError, MissingDownlevelFlags, WaitIdleError}, + device::{Device, DeviceError, MissingDownlevelFlags, WaitIdleError}, global::Global, - hal_api::HalApi, hal_label, id, resource::{self, Trackable}, }; @@ -30,7 +28,7 @@ const FRAME_TIMEOUT_MS: u32 = 1000; #[derive(Debug)] pub(crate) struct Presentation { - pub(crate) device: AnyDevice, // TODO(#5124): use device: Arc + pub(crate) device: Arc, pub(crate) config: wgt::SurfaceConfiguration>, pub(crate) acquired_texture: Option, } @@ -115,16 +113,14 @@ pub struct SurfaceOutput { } impl Global { - pub fn surface_get_current_texture( + pub fn surface_get_current_texture( &self, surface_id: id::SurfaceId, texture_id_in: Option, ) -> Result { profiling::scope!("SwapChain::get_next_texture"); - let hub = A::hub(self); - - let fid = hub.textures.prepare(texture_id_in); + let hub = &self.hub; let surface = self .surfaces @@ -132,17 +128,14 @@ impl Global { .map_err(|_| SurfaceError::Invalid)?; let (device, config) = if let Some(ref present) = *surface.presentation.lock() { - match present.device.downcast_clone::() { - Some(device) => { - device.check_is_valid()?; - (device, present.config.clone()) - } - None => return Err(SurfaceError::NotConfigured), - } + present.device.check_is_valid()?; + (present.device.clone(), present.config.clone()) } else { return Err(SurfaceError::NotConfigured); }; + let fid = hub.textures.prepare(device.backend(), texture_id_in); + #[cfg(feature = "trace")] if let Some(ref mut trace) = *device.trace.lock() { trace.add(Action::GetSurfaceTexture { @@ -153,7 +146,7 @@ impl Global { let fence = device.fence.read(); - let suf = surface.raw(A::VARIANT).unwrap(); + let suf = surface.raw(device.backend()).unwrap(); let (texture_id, status) = match unsafe { suf.acquire_texture( Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), @@ -259,13 +252,10 @@ impl Global { Ok(SurfaceOutput { status, texture_id }) } - pub fn surface_present( - &self, - surface_id: id::SurfaceId, - ) -> Result { + pub fn surface_present(&self, surface_id: id::SurfaceId) -> Result { profiling::scope!("SwapChain::present"); - let hub = A::hub(self); + let hub = &self.hub; let surface = self .surfaces @@ -278,7 +268,7 @@ impl Global { None => return Err(SurfaceError::NotConfigured), }; - let device = present.device.downcast_ref::().unwrap(); + let device = &present.device; #[cfg(feature = "trace")] if let Some(ref mut trace) = *device.trace.lock() { @@ -303,7 +293,7 @@ impl Global { .lock() .textures .remove(texture.tracker_index()); - let suf = surface.raw(A::VARIANT).unwrap(); + let suf = surface.raw(device.backend()).unwrap(); let exclusive_snatch_guard = device.snatchable_lock.write(); match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { @@ -335,13 +325,10 @@ impl Global { } } - pub fn surface_texture_discard( - &self, - surface_id: id::SurfaceId, - ) -> Result<(), SurfaceError> { + pub fn surface_texture_discard(&self, surface_id: id::SurfaceId) -> Result<(), SurfaceError> { profiling::scope!("SwapChain::discard"); - let hub = A::hub(self); + let hub = &self.hub; let surface = self .surfaces @@ -353,7 +340,7 @@ impl Global { None => return Err(SurfaceError::NotConfigured), }; - let device = present.device.downcast_ref::().unwrap(); + let device = &present.device; #[cfg(feature = "trace")] if let Some(ref mut trace) = *device.trace.lock() { @@ -378,7 +365,7 @@ impl Global { .lock() .textures .remove(texture.tracker_index()); - let suf = surface.raw(A::VARIANT); + let suf = surface.raw(device.backend()); let exclusive_snatch_guard = device.snatchable_lock.write(); match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { diff --git a/wgpu-core/src/registry.rs b/wgpu-core/src/registry.rs index 9183cc83bb..fa7e0def6c 100644 --- a/wgpu-core/src/registry.rs +++ b/wgpu-core/src/registry.rs @@ -1,7 +1,5 @@ use std::sync::Arc; -use wgt::Backend; - use crate::{ id::Id, identity::IdentityManager, @@ -40,21 +38,15 @@ pub(crate) struct Registry { // Must only contain an id which has either never been used or has been released from `storage` identity: Arc>, storage: RwLock>, - backend: Backend, } impl Registry { - pub(crate) fn new(backend: Backend) -> Self { + pub(crate) fn new() -> Self { Self { identity: Arc::new(IdentityManager::new()), storage: RwLock::new(rank::REGISTRY_STORAGE, Storage::new()), - backend, } } - - pub(crate) fn without_backend() -> Self { - Self::new(Backend::Empty) - } } #[must_use] @@ -89,14 +81,18 @@ impl FutureId<'_, T> { } impl Registry { - pub(crate) fn prepare(&self, id_in: Option>) -> FutureId { + pub(crate) fn prepare( + &self, + backend: wgt::Backend, + id_in: Option>, + ) -> FutureId { FutureId { id: match id_in { Some(id_in) => { self.identity.mark_as_used(id_in); id_in } - None => self.identity.process(self.backend), + None => self.identity.process(backend), }, data: &self.storage, } @@ -164,13 +160,13 @@ mod tests { #[test] fn simultaneous_registration() { - let registry = Registry::without_backend(); + let registry = Registry::new(); std::thread::scope(|s| { for _ in 0..5 { s.spawn(|| { for _ in 0..1000 { let value = Arc::new(TestData); - let new_id = registry.prepare(None); + let new_id = registry.prepare(wgt::Backend::Empty, None); let id = new_id.assign(value); registry.unregister(id); } diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 2b06799a24..184851fc2a 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -86,14 +86,14 @@ impl std::fmt::Display for ResourceErrorIdent { } } -pub(crate) trait ParentDevice: Labeled { - fn device(&self) -> &Arc>; +pub(crate) trait ParentDevice: Labeled { + fn device(&self) -> &Arc; fn is_equal(self: &Arc, other: &Arc) -> bool { Arc::ptr_eq(self, other) } - fn same_device_as>(&self, other: &O) -> Result<(), DeviceError> { + fn same_device_as(&self, other: &O) -> Result<(), DeviceError> { if Arc::ptr_eq(self.device(), other.device()) { Ok(()) } else { @@ -106,7 +106,7 @@ pub(crate) trait ParentDevice: Labeled { } } - fn same_device(&self, device: &Arc>) -> Result<(), DeviceError> { + fn same_device(&self, device: &Arc) -> Result<(), DeviceError> { if Arc::ptr_eq(self.device(), device) { Ok(()) } else { @@ -123,8 +123,8 @@ pub(crate) trait ParentDevice: Labeled { #[macro_export] macro_rules! impl_parent_device { ($ty:ident) => { - impl $crate::resource::ParentDevice for $ty { - fn device(&self) -> &Arc> { + impl $crate::resource::ParentDevice for $ty { + fn device(&self) -> &Arc { &self.device } } @@ -135,16 +135,6 @@ pub(crate) trait ResourceType { const TYPE: &'static str; } -// TODO(#5124): Remove the typed version. -#[macro_export] -macro_rules! impl_resource_type_generic { - ($ty:ident) => { - impl $crate::resource::ResourceType for $ty { - const TYPE: &'static str = stringify!($ty); - } - }; -} - #[macro_export] macro_rules! impl_resource_type { ($ty:ident) => { @@ -173,7 +163,7 @@ pub(crate) trait Labeled: ResourceType { #[macro_export] macro_rules! impl_labeled { ($ty:ident) => { - impl $crate::resource::Labeled for $ty { + impl $crate::resource::Labeled for $ty { fn label(&self) -> &str { &self.label } @@ -188,7 +178,7 @@ pub(crate) trait Trackable { #[macro_export] macro_rules! impl_trackable { ($ty:ident) => { - impl $crate::resource::Trackable for $ty { + impl $crate::resource::Trackable for $ty { fn tracker_index(&self) -> $crate::track::TrackerIndex { self.tracking_data.tracker_index() } @@ -230,11 +220,11 @@ pub enum BufferMapAsyncStatus { } #[derive(Debug)] -pub(crate) enum BufferMapState { +pub(crate) enum BufferMapState { /// Mapped at creation. - Init { staging_buffer: StagingBuffer }, + Init { staging_buffer: StagingBuffer }, /// Waiting for GPU to be done before mapping - Waiting(BufferPendingMapping), + Waiting(BufferPendingMapping), /// Mapped Active { mapping: hal::BufferMapping, @@ -246,9 +236,9 @@ pub(crate) enum BufferMapState { } #[cfg(send_sync)] -unsafe impl Send for BufferMapState {} +unsafe impl Send for BufferMapState {} #[cfg(send_sync)] -unsafe impl Sync for BufferMapState {} +unsafe impl Sync for BufferMapState {} #[repr(C)] pub struct BufferMapCallbackC { @@ -423,30 +413,30 @@ pub struct DestroyedResourceError(pub ResourceErrorIdent); pub type BufferAccessResult = Result<(), BufferAccessError>; #[derive(Debug)] -pub(crate) struct BufferPendingMapping { +pub(crate) struct BufferPendingMapping { pub(crate) range: Range, pub(crate) op: BufferMapOperation, // hold the parent alive while the mapping is active - pub(crate) _parent_buffer: Arc>, + pub(crate) _parent_buffer: Arc, } pub type BufferDescriptor<'a> = wgt::BufferDescriptor>; #[derive(Debug)] -pub struct Buffer { +pub struct Buffer { pub(crate) raw: Snatchable>, - pub(crate) device: Arc>, + pub(crate) device: Arc, pub(crate) usage: wgt::BufferUsages, pub(crate) size: wgt::BufferAddress, pub(crate) initialization_status: RwLock, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, - pub(crate) map_state: Mutex>, - pub(crate) bind_groups: Mutex>>>, + pub(crate) map_state: Mutex, + pub(crate) bind_groups: Mutex>>, } -impl Drop for Buffer { +impl Drop for Buffer { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); @@ -457,7 +447,7 @@ impl Drop for Buffer { } } -impl Buffer { +impl Buffer { pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a dyn hal::DynBuffer> { self.raw.get(guard).map(|b| b.as_ref()) } @@ -761,28 +751,28 @@ pub enum CreateBufferError { MissingDownlevelFlags(#[from] MissingDownlevelFlags), } -crate::impl_resource_type_generic!(Buffer); +crate::impl_resource_type!(Buffer); crate::impl_labeled!(Buffer); crate::impl_parent_device!(Buffer); -crate::impl_storage_item_generic!(Buffer); +crate::impl_storage_item!(Buffer); crate::impl_trackable!(Buffer); /// A buffer that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] -pub struct DestroyedBuffer { +pub struct DestroyedBuffer { raw: ManuallyDrop>, - device: Arc>, + device: Arc, label: String, - bind_groups: Vec>>, + bind_groups: Vec>, } -impl DestroyedBuffer { +impl DestroyedBuffer { pub fn label(&self) -> &dyn Debug { &self.label } } -impl Drop for DestroyedBuffer { +impl Drop for DestroyedBuffer { fn drop(&mut self) { let mut deferred = self.device.deferred_destroy.lock(); for bind_group in self.bind_groups.drain(..) { @@ -800,9 +790,9 @@ impl Drop for DestroyedBuffer { } #[cfg(send_sync)] -unsafe impl Send for StagingBuffer {} +unsafe impl Send for StagingBuffer {} #[cfg(send_sync)] -unsafe impl Sync for StagingBuffer {} +unsafe impl Sync for StagingBuffer {} /// A temporary buffer, consumed by the command that uses it. /// @@ -824,16 +814,16 @@ unsafe impl Sync for StagingBuffer {} /// [`queue_write_texture`]: Global::queue_write_texture /// [`Device::pending_writes`]: crate::device::Device #[derive(Debug)] -pub struct StagingBuffer { +pub struct StagingBuffer { raw: Box, - device: Arc>, + device: Arc, pub(crate) size: wgt::BufferSize, is_coherent: bool, ptr: NonNull, } -impl StagingBuffer { - pub(crate) fn new(device: &Arc>, size: wgt::BufferSize) -> Result { +impl StagingBuffer { + pub(crate) fn new(device: &Arc, size: wgt::BufferSize) -> Result { profiling::scope!("StagingBuffer::new"); let stage_desc = hal::BufferDescriptor { label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags), @@ -901,7 +891,7 @@ impl StagingBuffer { } } - pub(crate) fn flush(self) -> FlushedStagingBuffer { + pub(crate) fn flush(self) -> FlushedStagingBuffer { let device = self.device.raw(); if !self.is_coherent { #[allow(clippy::single_range_in_vec_init)] @@ -923,23 +913,23 @@ impl StagingBuffer { } } -crate::impl_resource_type_generic!(StagingBuffer); -crate::impl_storage_item_generic!(StagingBuffer); +crate::impl_resource_type!(StagingBuffer); +crate::impl_storage_item!(StagingBuffer); #[derive(Debug)] -pub struct FlushedStagingBuffer { +pub struct FlushedStagingBuffer { raw: ManuallyDrop>, - device: Arc>, + device: Arc, pub(crate) size: wgt::BufferSize, } -impl FlushedStagingBuffer { +impl FlushedStagingBuffer { pub(crate) fn raw(&self) -> &dyn hal::DynBuffer { self.raw.as_ref() } } -impl Drop for FlushedStagingBuffer { +impl Drop for FlushedStagingBuffer { fn drop(&mut self) { resource_log!("Destroy raw StagingBuffer"); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -987,9 +977,9 @@ pub enum TextureClearMode { } #[derive(Debug)] -pub struct Texture { +pub struct Texture { pub(crate) inner: Snatchable, - pub(crate) device: Arc>, + pub(crate) device: Arc, pub(crate) desc: wgt::TextureDescriptor<(), Vec>, pub(crate) hal_usage: hal::TextureUses, pub(crate) format_features: wgt::TextureFormatFeatures, @@ -999,13 +989,13 @@ pub struct Texture { pub(crate) label: String, pub(crate) tracking_data: TrackingData, pub(crate) clear_mode: TextureClearMode, - pub(crate) views: Mutex>>>, - pub(crate) bind_groups: Mutex>>>, + pub(crate) views: Mutex>>, + pub(crate) bind_groups: Mutex>>, } -impl Texture { +impl Texture { pub(crate) fn new( - device: &Arc>, + device: &Arc, inner: TextureInner, hal_usage: hal::TextureUses, desc: &TextureDescriptor, @@ -1056,7 +1046,7 @@ impl Texture { } } -impl Drop for Texture { +impl Drop for Texture { fn drop(&mut self) { match self.clear_mode { TextureClearMode::Surface { @@ -1092,7 +1082,7 @@ impl Drop for Texture { } } -impl Texture { +impl Texture { pub(crate) fn try_inner<'a>( &'a self, guard: &'a SnatchGuard, @@ -1208,7 +1198,7 @@ impl Global { ) -> R { profiling::scope!("Buffer::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(buffer) = hub.buffers.get(id) { let snatch_guard = buffer.device.snatchable_lock.read(); @@ -1231,7 +1221,7 @@ impl Global { ) -> R { profiling::scope!("Texture::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(texture) = hub.textures.get(id) { let snatch_guard = texture.device.snatchable_lock.read(); @@ -1255,7 +1245,7 @@ impl Global { ) -> R { profiling::scope!("TextureView::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(texture_view) = hub.texture_views.get(id) { let snatch_guard = texture_view.device.snatchable_lock.read(); @@ -1279,7 +1269,7 @@ impl Global { ) -> R { profiling::scope!("Adapter::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; let adapter = hub.adapters.get(id).ok(); let hal_adapter = adapter .as_ref() @@ -1299,7 +1289,7 @@ impl Global { ) -> R { profiling::scope!("Device::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; let device = hub.devices.get(id).ok(); let hal_device = device .as_ref() @@ -1319,7 +1309,7 @@ impl Global { ) -> R { profiling::scope!("Device::fence_as_hal"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(device) = hub.devices.get(id) { let fence = device.fence.read(); @@ -1361,7 +1351,7 @@ impl Global { ) -> R { profiling::scope!("CommandEncoder::as_hal"); - let hub = A::hub(self); + let hub = &self.hub; if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) { let mut cmd_buf_data = cmd_buf.data.lock(); @@ -1380,21 +1370,21 @@ impl Global { /// A texture that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] -pub struct DestroyedTexture { +pub struct DestroyedTexture { raw: ManuallyDrop>, - views: Vec>>, - bind_groups: Vec>>, - device: Arc>, + views: Vec>, + bind_groups: Vec>, + device: Arc, label: String, } -impl DestroyedTexture { +impl DestroyedTexture { pub fn label(&self) -> &dyn Debug { &self.label } } -impl Drop for DestroyedTexture { +impl Drop for DestroyedTexture { fn drop(&mut self) { let device = &self.device; @@ -1508,13 +1498,13 @@ pub enum CreateTextureError { MissingDownlevelFlags(#[from] MissingDownlevelFlags), } -crate::impl_resource_type_generic!(Texture); +crate::impl_resource_type!(Texture); crate::impl_labeled!(Texture); crate::impl_parent_device!(Texture); -crate::impl_storage_item_generic!(Texture); +crate::impl_storage_item!(Texture); crate::impl_trackable!(Texture); -impl Borrow for Texture { +impl Borrow for Texture { fn borrow(&self) -> &TextureSelector { &self.full_range } @@ -1575,11 +1565,11 @@ pub enum TextureViewNotRenderableReason { } #[derive(Debug)] -pub struct TextureView { +pub struct TextureView { pub(crate) raw: Snatchable>, // if it's a surface texture - it's none - pub(crate) parent: Arc>, - pub(crate) device: Arc>, + pub(crate) parent: Arc, + pub(crate) device: Arc, pub(crate) desc: HalTextureViewDescriptor, pub(crate) format_features: wgt::TextureFormatFeatures, /// This is `Err` only if the texture view is not renderable @@ -1591,7 +1581,7 @@ pub struct TextureView { pub(crate) tracking_data: TrackingData, } -impl Drop for TextureView { +impl Drop for TextureView { fn drop(&mut self) { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); @@ -1602,7 +1592,7 @@ impl Drop for TextureView { } } -impl TextureView { +impl TextureView { pub(crate) fn raw<'a>( &'a self, snatch_guard: &'a SnatchGuard, @@ -1676,10 +1666,10 @@ pub enum CreateTextureViewError { #[non_exhaustive] pub enum TextureViewDestroyError {} -crate::impl_resource_type_generic!(TextureView); +crate::impl_resource_type!(TextureView); crate::impl_labeled!(TextureView); crate::impl_parent_device!(TextureView); -crate::impl_storage_item_generic!(TextureView); +crate::impl_storage_item!(TextureView); crate::impl_trackable!(TextureView); /// Describes a [`Sampler`] @@ -1712,9 +1702,9 @@ pub struct SamplerDescriptor<'a> { } #[derive(Debug)] -pub struct Sampler { +pub struct Sampler { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, @@ -1724,7 +1714,7 @@ pub struct Sampler { pub(crate) filtering: bool, } -impl Drop for Sampler { +impl Drop for Sampler { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -1735,7 +1725,7 @@ impl Drop for Sampler { } } -impl Sampler { +impl Sampler { pub(crate) fn raw(&self) -> &dyn hal::DynSampler { self.raw.as_ref() } @@ -1785,10 +1775,10 @@ pub enum CreateSamplerError { MissingFeatures(#[from] MissingFeatures), } -crate::impl_resource_type_generic!(Sampler); +crate::impl_resource_type!(Sampler); crate::impl_labeled!(Sampler); crate::impl_parent_device!(Sampler); -crate::impl_storage_item_generic!(Sampler); +crate::impl_storage_item!(Sampler); crate::impl_trackable!(Sampler); #[derive(Clone, Debug, Error)] @@ -1807,16 +1797,16 @@ pub enum CreateQuerySetError { pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor>; #[derive(Debug)] -pub struct QuerySet { +pub struct QuerySet { pub(crate) raw: ManuallyDrop>, - pub(crate) device: Arc>, + pub(crate) device: Arc, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, pub(crate) desc: wgt::QuerySetDescriptor<()>, } -impl Drop for QuerySet { +impl Drop for QuerySet { fn drop(&mut self) { resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. @@ -1827,13 +1817,13 @@ impl Drop for QuerySet { } } -crate::impl_resource_type_generic!(QuerySet); +crate::impl_resource_type!(QuerySet); crate::impl_labeled!(QuerySet); crate::impl_parent_device!(QuerySet); -crate::impl_storage_item_generic!(QuerySet); +crate::impl_storage_item!(QuerySet); crate::impl_trackable!(QuerySet); -impl QuerySet { +impl QuerySet { pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet { self.raw.as_ref() } diff --git a/wgpu-core/src/storage.rs b/wgpu-core/src/storage.rs index 0adcf51abd..c5e91eedd4 100644 --- a/wgpu-core/src/storage.rs +++ b/wgpu-core/src/storage.rs @@ -28,16 +28,6 @@ pub(crate) trait StorageItem: ResourceType { type Marker: Marker; } -// TODO(#5124): Remove the typed version. -#[macro_export] -macro_rules! impl_storage_item_generic { - ($ty:ident) => { - impl $crate::storage::StorageItem for $ty { - type Marker = $crate::id::markers::$ty; - } - }; -} - #[macro_export] macro_rules! impl_storage_item { ($ty:ident) => { diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index ea670de35a..13629dfbc9 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -8,7 +8,6 @@ use std::sync::{Arc, Weak}; use super::{PendingTransition, TrackerIndex}; use crate::{ - hal_api::HalApi, resource::{Buffer, Trackable}, snatch::SnatchGuard, track::{ @@ -39,10 +38,10 @@ impl ResourceUses for BufferUses { /// Stores a bind group's buffers + their usages (within the bind group). #[derive(Debug)] -pub(crate) struct BufferBindGroupState { - buffers: Vec<(Arc>, BufferUses)>, +pub(crate) struct BufferBindGroupState { + buffers: Vec<(Arc, BufferUses)>, } -impl BufferBindGroupState { +impl BufferBindGroupState { pub fn new() -> Self { Self { buffers: Vec::new(), @@ -68,19 +67,19 @@ impl BufferBindGroupState { } /// Adds the given resource with the given state. - pub fn insert_single(&mut self, buffer: Arc>, state: BufferUses) { + pub fn insert_single(&mut self, buffer: Arc, state: BufferUses) { self.buffers.push((buffer, state)); } } /// Stores all buffer state within a single usage scope. #[derive(Debug)] -pub(crate) struct BufferUsageScope { +pub(crate) struct BufferUsageScope { state: Vec, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, } -impl Default for BufferUsageScope { +impl Default for BufferUsageScope { fn default() -> Self { Self { state: Vec::new(), @@ -89,7 +88,7 @@ impl Default for BufferUsageScope { } } -impl BufferUsageScope { +impl BufferUsageScope { fn tracker_assert_in_bounds(&self, index: usize) { strict_assert!(index < self.state.len()); self.metadata.tracker_assert_in_bounds(index); @@ -129,7 +128,7 @@ impl BufferUsageScope { /// method is called. pub unsafe fn merge_bind_group( &mut self, - bind_group: &BufferBindGroupState, + bind_group: &BufferBindGroupState, ) -> Result<(), ResourceUsageCompatibilityError> { for &(ref resource, state) in bind_group.buffers.iter() { let index = resource.tracker_index().as_usize(); @@ -199,7 +198,7 @@ impl BufferUsageScope { /// the vectors will be extended. A call to set_size is not needed. pub fn merge_single( &mut self, - buffer: &Arc>, + buffer: &Arc, new_state: BufferUses, ) -> Result<(), ResourceUsageCompatibilityError> { let index = buffer.tracker_index().as_usize(); @@ -225,16 +224,16 @@ impl BufferUsageScope { } /// Stores all buffer state within a command buffer. -pub(crate) struct BufferTracker { +pub(crate) struct BufferTracker { start: Vec, end: Vec, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, temp: Vec>, } -impl BufferTracker { +impl BufferTracker { pub fn new() -> Self { Self { start: Vec::new(), @@ -271,12 +270,12 @@ impl BufferTracker { } /// Returns true if the given buffer is tracked. - pub fn contains(&self, buffer: &Buffer) -> bool { + pub fn contains(&self, buffer: &Buffer) -> bool { self.metadata.contains(buffer.tracker_index().as_usize()) } /// Returns a list of all buffers tracked. - pub fn used_resources(&self) -> impl Iterator>> + '_ { + pub fn used_resources(&self) -> impl Iterator> + '_ { self.metadata.owned_resources() } @@ -301,7 +300,7 @@ impl BufferTracker { /// the vectors will be extended. A call to set_size is not needed. pub fn set_single( &mut self, - buffer: &Arc>, + buffer: &Arc, state: BufferUses, ) -> Option> { let index: usize = buffer.tracker_index().as_usize(); @@ -374,7 +373,7 @@ impl BufferTracker { /// /// If the ID is higher than the length of internal vectors, /// the vectors will be extended. A call to set_size is not needed. - pub fn set_from_usage_scope(&mut self, scope: &BufferUsageScope) { + pub fn set_from_usage_scope(&mut self, scope: &BufferUsageScope) { let incoming_size = scope.state.len(); if incoming_size > self.start.len() { self.set_size(incoming_size); @@ -422,7 +421,7 @@ impl BufferTracker { /// method is called. pub unsafe fn set_and_remove_from_usage_scope_sparse( &mut self, - scope: &mut BufferUsageScope, + scope: &mut BufferUsageScope, index_source: impl IntoIterator, ) { let incoming_size = scope.state.len(); @@ -461,13 +460,13 @@ impl BufferTracker { } /// Stores all buffer state within a device. -pub(crate) struct DeviceBufferTracker { +pub(crate) struct DeviceBufferTracker { current_states: Vec, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, temp: Vec>, } -impl DeviceBufferTracker { +impl DeviceBufferTracker { pub fn new() -> Self { Self { current_states: Vec::new(), @@ -490,14 +489,14 @@ impl DeviceBufferTracker { } /// Returns a list of all buffers tracked. - pub fn used_resources(&self) -> impl Iterator>> + '_ { + pub fn used_resources(&self) -> impl Iterator> + '_ { self.metadata.owned_resources() } /// Inserts a single buffer and its state into the resource tracker. /// /// If the resource already exists in the tracker, it will be overwritten. - pub fn insert_single(&mut self, buffer: &Arc>, state: BufferUses) { + pub fn insert_single(&mut self, buffer: &Arc, state: BufferUses) { let index = buffer.tracker_index().as_usize(); self.allow_index(index); @@ -525,7 +524,7 @@ impl DeviceBufferTracker { /// is returned. No more than one transition is needed. pub fn set_single( &mut self, - buffer: &Arc>, + buffer: &Arc, state: BufferUses, ) -> Option> { let index: usize = buffer.tracker_index().as_usize(); @@ -555,7 +554,7 @@ impl DeviceBufferTracker { /// those transitions are returned. pub fn set_from_tracker_and_drain_transitions<'a, 'b: 'a>( &'a mut self, - tracker: &'a BufferTracker, + tracker: &'a BufferTracker, snatch_guard: &'b SnatchGuard<'b>, ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { @@ -621,14 +620,14 @@ impl BufferStateProvider<'_> { /// Indexes must be valid indexes into all arrays passed in /// to this function, either directly or via metadata or provider structs. #[inline(always)] -unsafe fn insert_or_merge( +unsafe fn insert_or_merge( start_states: Option<&mut [BufferUses]>, current_states: &mut [BufferUses], - resource_metadata: &mut ResourceMetadata>>, + resource_metadata: &mut ResourceMetadata>, index32: u32, index: usize, state_provider: BufferStateProvider<'_>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, ) -> Result<(), ResourceUsageCompatibilityError> { let currently_owned = unsafe { resource_metadata.contains_unchecked(index) }; @@ -677,14 +676,14 @@ unsafe fn insert_or_merge( /// Indexes must be valid indexes into all arrays passed in /// to this function, either directly or via metadata or provider structs. #[inline(always)] -unsafe fn insert_or_barrier_update( +unsafe fn insert_or_barrier_update( start_states: Option<&mut [BufferUses]>, current_states: &mut [BufferUses], - resource_metadata: &mut ResourceMetadata>>, + resource_metadata: &mut ResourceMetadata>, index: usize, start_state_provider: BufferStateProvider<'_>, end_state_provider: Option>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, barriers: &mut Vec>, ) { let currently_owned = unsafe { resource_metadata.contains_unchecked(index) }; @@ -741,12 +740,12 @@ unsafe fn insert( } #[inline(always)] -unsafe fn merge( +unsafe fn merge( current_states: &mut [BufferUses], _index32: u32, index: usize, state_provider: BufferStateProvider<'_>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, ) -> Result<(), ResourceUsageCompatibilityError> { let current_state = unsafe { current_states.get_unchecked_mut(index) }; let new_state = unsafe { state_provider.get_state(index) }; diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index a75092d8be..1c2718981b 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -1,7 +1,7 @@ /*! Resource State and Lifetime Trackers These structures are responsible for keeping track of resource state, -generating barriers where needed, and making sure resources are kept +generating barriers where needednd making sure resources are kept alive until the trackers die. ## General Architecture @@ -35,7 +35,7 @@ Stateless trackers only store metadata and own the given resource. ## Use Case Within each type of tracker, the trackers are further split into 3 different -use cases, Bind Group, Usage Scope, and a full Tracker. +use cases, Bind Group, Usage Scopend a full Tracker. Bind Group trackers are just a list of different resources, their refcount, and how they are used. Textures are used via a selector and a usage type. @@ -60,7 +60,7 @@ not always contain every resource. Some resources (or even most resources) go unused in any given command buffer. So to help speed up the process of iterating through possibly thousands of resources, we use a bit vector to represent if a resource is in the buffer or not. This allows us extremely efficient memory -utilization, as well as being able to bail out of whole blocks of 32-64 resources +utilizations well as being able to bail out of whole blocks of 32-64 resources with a single usize comparison with zero. In practice this means that merging partially resident buffers is extremely quick. @@ -103,7 +103,6 @@ mod texture; use crate::{ binding_model, command, - hal_api::HalApi, lock::{rank, Mutex}, pipeline, resource::{self, Labeled, ResourceErrorIdent}, @@ -257,9 +256,9 @@ pub(crate) type PendingTransitionList = Vec> impl PendingTransition { /// Produce the hal barrier corresponding to the transition. - pub fn into_hal<'a, A: HalApi>( + pub fn into_hal<'a>( self, - buf: &'a resource::Buffer, + buf: &'a resource::Buffer, snatch_guard: &'a SnatchGuard<'a>, ) -> hal::BufferBarrier<'a, dyn hal::DynBuffer> { let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed"); @@ -352,8 +351,8 @@ pub enum ResourceUsageCompatibilityError { } impl ResourceUsageCompatibilityError { - fn from_buffer( - buffer: &resource::Buffer, + fn from_buffer( + buffer: &resource::Buffer, current_state: hal::BufferUses, new_state: hal::BufferUses, ) -> Self { @@ -366,8 +365,8 @@ impl ResourceUsageCompatibilityError { } } - fn from_texture( - texture: &resource::Texture, + fn from_texture( + texture: &resource::Texture, selector: TextureSelector, current_state: hal::TextureUses, new_state: hal::TextureUses, @@ -417,13 +416,13 @@ impl fmt::Display for InvalidUse { /// All bind group states are sorted by their ID so that when adding to a tracker, /// they are added in the most efficient order possible (ascending order). #[derive(Debug)] -pub(crate) struct BindGroupStates { - pub buffers: BufferBindGroupState, - pub views: TextureViewBindGroupState, - pub samplers: StatelessTracker>, +pub(crate) struct BindGroupStates { + pub buffers: BufferBindGroupState, + pub views: TextureViewBindGroupState, + pub samplers: StatelessTracker, } -impl BindGroupStates { +impl BindGroupStates { pub fn new() -> Self { Self { buffers: BufferBindGroupState::new(), @@ -450,15 +449,15 @@ impl BindGroupStates { /// that are not normally included in a usage scope, but are used by render bundles /// and need to be owned by the render bundles. #[derive(Debug)] -pub(crate) struct RenderBundleScope { - pub buffers: BufferUsageScope, - pub textures: TextureUsageScope, +pub(crate) struct RenderBundleScope { + pub buffers: BufferUsageScope, + pub textures: TextureUsageScope, // Don't need to track views and samplers, they are never used directly, only by bind groups. - pub bind_groups: StatelessTracker>, - pub render_pipelines: StatelessTracker>, + pub bind_groups: StatelessTracker, + pub render_pipelines: StatelessTracker, } -impl RenderBundleScope { +impl RenderBundleScope { /// Create the render bundle scope and pull the maximum IDs from the hubs. pub fn new() -> Self { Self { @@ -471,7 +470,7 @@ impl RenderBundleScope { /// Merge the inner contents of a bind group into the render bundle tracker. /// - /// Only stateful things are merged in here, all other resources are owned + /// Only stateful things are merged in herell other resources are owned /// indirectly by the bind group. /// /// # Safety @@ -480,7 +479,7 @@ impl RenderBundleScope { /// length of the storage given at the call to `new`. pub unsafe fn merge_bind_group( &mut self, - bind_group: &BindGroupStates, + bind_group: &BindGroupStates, ) -> Result<(), ResourceUsageCompatibilityError> { unsafe { self.buffers.merge_bind_group(&bind_group.buffers)? }; unsafe { self.textures.merge_bind_group(&bind_group.views)? }; @@ -492,18 +491,18 @@ impl RenderBundleScope { /// A pool for storing the memory used by [`UsageScope`]s. We take and store this memory when the /// scope is dropped to avoid reallocating. The memory required only grows and allocation cost is /// significant when a large number of resources have been used. -pub(crate) type UsageScopePool = Mutex, TextureUsageScope)>>; +pub(crate) type UsageScopePool = Mutex>; /// A usage scope tracker. Only needs to store stateful resources as stateless /// resources cannot possibly have a usage conflict. #[derive(Debug)] -pub(crate) struct UsageScope<'a, A: HalApi> { - pub pool: &'a UsageScopePool, - pub buffers: BufferUsageScope, - pub textures: TextureUsageScope, +pub(crate) struct UsageScope<'a> { + pub pool: &'a UsageScopePool, + pub buffers: BufferUsageScope, + pub textures: TextureUsageScope, } -impl<'a, A: HalApi> Drop for UsageScope<'a, A> { +impl<'a> Drop for UsageScope<'a> { fn drop(&mut self) { // clear vecs and push into pool self.buffers.clear(); @@ -515,14 +514,14 @@ impl<'a, A: HalApi> Drop for UsageScope<'a, A> { } } -impl UsageScope<'static, A> { +impl UsageScope<'static> { pub fn new_pooled<'d>( - pool: &'d UsageScopePool, + pool: &'d UsageScopePool, tracker_indices: &TrackerIndexAllocators, - ) -> UsageScope<'d, A> { + ) -> UsageScope<'d> { let pooled = pool.lock().pop().unwrap_or_default(); - let mut scope = UsageScope::<'d, A> { + let mut scope = UsageScope::<'d> { pool, buffers: pooled.0, textures: pooled.1, @@ -534,10 +533,10 @@ impl UsageScope<'static, A> { } } -impl<'a, A: HalApi> UsageScope<'a, A> { +impl<'a> UsageScope<'a> { /// Merge the inner contents of a bind group into the usage scope. /// - /// Only stateful things are merged in here, all other resources are owned + /// Only stateful things are merged in herell other resources are owned /// indirectly by the bind group. /// /// # Safety @@ -546,7 +545,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> { /// length of the storage given at the call to `new`. pub unsafe fn merge_bind_group( &mut self, - bind_group: &BindGroupStates, + bind_group: &BindGroupStates, ) -> Result<(), ResourceUsageCompatibilityError> { unsafe { self.buffers.merge_bind_group(&bind_group.buffers)?; @@ -558,7 +557,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> { /// Merge the inner contents of a bind group into the usage scope. /// - /// Only stateful things are merged in here, all other resources are owned + /// Only stateful things are merged in herell other resources are owned /// indirectly by a bind group or are merged directly into the command buffer tracker. /// /// # Safety @@ -567,7 +566,7 @@ impl<'a, A: HalApi> UsageScope<'a, A> { /// length of the storage given at the call to `new`. pub unsafe fn merge_render_bundle( &mut self, - render_bundle: &RenderBundleScope, + render_bundle: &RenderBundleScope, ) -> Result<(), ResourceUsageCompatibilityError> { self.buffers.merge_usage_scope(&render_bundle.buffers)?; self.textures.merge_usage_scope(&render_bundle.textures)?; @@ -577,12 +576,12 @@ impl<'a, A: HalApi> UsageScope<'a, A> { } /// A tracker used by Device. -pub(crate) struct DeviceTracker { - pub buffers: DeviceBufferTracker, - pub textures: DeviceTextureTracker, +pub(crate) struct DeviceTracker { + pub buffers: DeviceBufferTracker, + pub textures: DeviceTextureTracker, } -impl DeviceTracker { +impl DeviceTracker { pub fn new() -> Self { Self { buffers: DeviceBufferTracker::new(), @@ -592,18 +591,18 @@ impl DeviceTracker { } /// A full double sided tracker used by CommandBuffers. -pub(crate) struct Tracker { - pub buffers: BufferTracker, - pub textures: TextureTracker, - pub views: StatelessTracker>, - pub bind_groups: StatelessTracker>, - pub compute_pipelines: StatelessTracker>, - pub render_pipelines: StatelessTracker>, - pub bundles: StatelessTracker>, - pub query_sets: StatelessTracker>, +pub(crate) struct Tracker { + pub buffers: BufferTracker, + pub textures: TextureTracker, + pub views: StatelessTracker, + pub bind_groups: StatelessTracker, + pub compute_pipelines: StatelessTracker, + pub render_pipelines: StatelessTracker, + pub bundles: StatelessTracker, + pub query_sets: StatelessTracker, } -impl Tracker { +impl Tracker { pub fn new() -> Self { Self { buffers: BufferTracker::new(), @@ -632,7 +631,7 @@ impl Tracker { /// bind group as a source of which IDs to look at. The bind groups /// must have first been added to the usage scope. /// - /// Only stateful things are merged in here, all other resources are owned + /// Only stateful things are merged in herell other resources are owned /// indirectly by the bind group. /// /// # Safety @@ -641,8 +640,8 @@ impl Tracker { /// value given to `set_size` pub unsafe fn set_and_remove_from_usage_scope_sparse( &mut self, - scope: &mut UsageScope, - bind_group: &BindGroupStates, + scope: &mut UsageScope, + bind_group: &BindGroupStates, ) { unsafe { self.buffers.set_and_remove_from_usage_scope_sparse( diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index 9b11527645..1c74bffd97 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -20,7 +20,6 @@ use super::{range::RangedStates, PendingTransition, PendingTransitionList, TrackerIndex}; use crate::{ - hal_api::HalApi, resource::{Texture, TextureInner, TextureView, Trackable}, snatch::SnatchGuard, track::{ @@ -152,10 +151,10 @@ impl ComplexTextureState { /// Stores a bind group's texture views + their usages (within the bind group). #[derive(Debug)] -pub(crate) struct TextureViewBindGroupState { - views: Vec<(Arc>, TextureUses)>, +pub(crate) struct TextureViewBindGroupState { + views: Vec<(Arc, TextureUses)>, } -impl TextureViewBindGroupState { +impl TextureViewBindGroupState { pub fn new() -> Self { Self { views: Vec::new() } } @@ -170,7 +169,7 @@ impl TextureViewBindGroupState { } /// Adds the given resource with the given state. - pub fn insert_single(&mut self, view: Arc>, usage: TextureUses) { + pub fn insert_single(&mut self, view: Arc, usage: TextureUses) { self.views.push((view, usage)); } } @@ -202,12 +201,12 @@ impl TextureStateSet { /// Stores all texture state within a single usage scope. #[derive(Debug)] -pub(crate) struct TextureUsageScope { +pub(crate) struct TextureUsageScope { set: TextureStateSet, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, } -impl Default for TextureUsageScope { +impl Default for TextureUsageScope { fn default() -> Self { Self { set: TextureStateSet::new(), @@ -216,7 +215,7 @@ impl Default for TextureUsageScope { } } -impl TextureUsageScope { +impl TextureUsageScope { fn tracker_assert_in_bounds(&self, index: usize) { self.metadata.tracker_assert_in_bounds(index); @@ -305,7 +304,7 @@ impl TextureUsageScope { /// method is called. pub unsafe fn merge_bind_group( &mut self, - bind_group: &TextureViewBindGroupState, + bind_group: &TextureViewBindGroupState, ) -> Result<(), ResourceUsageCompatibilityError> { for (view, usage) in bind_group.views.iter() { unsafe { self.merge_single(&view.parent, Some(view.selector.clone()), *usage)? }; @@ -329,7 +328,7 @@ impl TextureUsageScope { /// method is called. pub unsafe fn merge_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: Option, new_state: TextureUses, ) -> Result<(), ResourceUsageCompatibilityError> { @@ -353,26 +352,26 @@ impl TextureUsageScope { } } -pub(crate) trait TextureTrackerSetSingle { +pub(crate) trait TextureTrackerSetSingle { fn set_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: TextureSelector, new_state: TextureUses, ) -> Drain<'_, PendingTransition>; } /// Stores all texture state within a command buffer. -pub(crate) struct TextureTracker { +pub(crate) struct TextureTracker { start_set: TextureStateSet, end_set: TextureStateSet, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, temp: Vec>, } -impl TextureTracker { +impl TextureTracker { pub fn new() -> Self { Self { start_set: TextureStateSet::new(), @@ -425,12 +424,12 @@ impl TextureTracker { } /// Returns true if the tracker owns the given texture. - pub fn contains(&self, texture: &Texture) -> bool { + pub fn contains(&self, texture: &Texture) -> bool { self.metadata.contains(texture.tracker_index().as_usize()) } /// Returns a list of all textures tracked. - pub fn used_resources(&self) -> impl Iterator>> + '_ { + pub fn used_resources(&self) -> impl Iterator> + '_ { self.metadata.owned_resources() } @@ -461,7 +460,7 @@ impl TextureTracker { /// the vectors will be extended. A call to set_size is not needed. pub fn set_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: TextureSelector, new_state: TextureUses, ) -> Drain<'_, PendingTransition> { @@ -539,7 +538,7 @@ impl TextureTracker { /// /// If the ID is higher than the length of internal vectors, /// the vectors will be extended. A call to set_size is not needed. - pub fn set_from_usage_scope(&mut self, scope: &TextureUsageScope) { + pub fn set_from_usage_scope(&mut self, scope: &TextureUsageScope) { let incoming_size = scope.set.simple.len(); if incoming_size > self.start_set.simple.len() { self.set_size(incoming_size); @@ -587,8 +586,8 @@ impl TextureTracker { /// method is called. pub unsafe fn set_and_remove_from_usage_scope_sparse( &mut self, - scope: &mut TextureUsageScope, - bind_group_state: &TextureViewBindGroupState, + scope: &mut TextureUsageScope, + bind_group_state: &TextureViewBindGroupState, ) { let incoming_size = scope.set.simple.len(); if incoming_size > self.start_set.simple.len() { @@ -624,10 +623,10 @@ impl TextureTracker { } } -impl TextureTrackerSetSingle for TextureTracker { +impl TextureTrackerSetSingle for TextureTracker { fn set_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: TextureSelector, new_state: TextureUses, ) -> Drain<'_, PendingTransition> { @@ -636,13 +635,13 @@ impl TextureTrackerSetSingle for TextureTracker { } /// Stores all texture state within a device. -pub(crate) struct DeviceTextureTracker { +pub(crate) struct DeviceTextureTracker { current_state_set: TextureStateSet, - metadata: ResourceMetadata>>, + metadata: ResourceMetadata>, temp: Vec>, } -impl DeviceTextureTracker { +impl DeviceTextureTracker { pub fn new() -> Self { Self { current_state_set: TextureStateSet::new(), @@ -674,14 +673,14 @@ impl DeviceTextureTracker { } /// Returns a list of all textures tracked. - pub fn used_resources(&self) -> impl Iterator>> + '_ { + pub fn used_resources(&self) -> impl Iterator> + '_ { self.metadata.owned_resources() } /// Inserts a single texture and a state into the resource tracker. /// /// If the resource already exists in the tracker, it will be overwritten. - pub fn insert_single(&mut self, texture: &Arc>, usage: TextureUses) { + pub fn insert_single(&mut self, texture: &Arc, usage: TextureUses) { let index = texture.tracker_index().as_usize(); self.allow_index(index); @@ -710,7 +709,7 @@ impl DeviceTextureTracker { /// is returned. pub fn set_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: TextureSelector, new_state: TextureUses, ) -> Drain<'_, PendingTransition> { @@ -752,7 +751,7 @@ impl DeviceTextureTracker { /// those transitions are returned. pub fn set_from_tracker_and_drain_transitions<'a, 'b: 'a>( &'a mut self, - tracker: &'a TextureTracker, + tracker: &'a TextureTracker, snatch_guard: &'b SnatchGuard<'b>, ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { @@ -796,7 +795,7 @@ impl DeviceTextureTracker { /// those transitions are returned. pub fn set_from_usage_scope_and_drain_transitions<'a, 'b: 'a>( &'a mut self, - scope: &'a TextureUsageScope, + scope: &'a TextureUsageScope, snatch_guard: &'b SnatchGuard<'b>, ) -> impl Iterator> { for index in scope.metadata.owned_indices() { @@ -856,10 +855,10 @@ impl DeviceTextureTracker { } } -impl TextureTrackerSetSingle for DeviceTextureTracker { +impl TextureTrackerSetSingle for DeviceTextureTracker { fn set_single( &mut self, - texture: &Arc>, + texture: &Arc, selector: TextureSelector, new_state: TextureUses, ) -> Drain<'_, PendingTransition> { @@ -978,13 +977,13 @@ impl<'a> TextureStateProvider<'a> { /// Indexes must be valid indexes into all arrays passed in /// to this function, either directly or via metadata or provider structs. #[inline(always)] -unsafe fn insert_or_merge( +unsafe fn insert_or_merge( texture_selector: &TextureSelector, current_state_set: &mut TextureStateSet, - resource_metadata: &mut ResourceMetadata>>, + resource_metadata: &mut ResourceMetadata>, index: usize, state_provider: TextureStateProvider<'_>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, ) -> Result<(), ResourceUsageCompatibilityError> { let currently_owned = unsafe { resource_metadata.contains_unchecked(index) }; @@ -1034,15 +1033,15 @@ unsafe fn insert_or_merge( /// Indexes must be valid indexes into all arrays passed in /// to this function, either directly or via metadata or provider structs. #[inline(always)] -unsafe fn insert_or_barrier_update( +unsafe fn insert_or_barrier_update( texture_selector: &TextureSelector, start_state: Option<&mut TextureStateSet>, current_state_set: &mut TextureStateSet, - resource_metadata: &mut ResourceMetadata>>, + resource_metadata: &mut ResourceMetadata>, index: usize, start_state_provider: TextureStateProvider<'_>, end_state_provider: Option>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, barriers: &mut Vec>, ) { let currently_owned = unsafe { resource_metadata.contains_unchecked(index) }; @@ -1163,12 +1162,12 @@ unsafe fn insert( } #[inline(always)] -unsafe fn merge( +unsafe fn merge( texture_selector: &TextureSelector, current_state_set: &mut TextureStateSet, index: usize, state_provider: TextureStateProvider<'_>, - metadata_provider: ResourceMetadataProvider<'_, Arc>>, + metadata_provider: ResourceMetadataProvider<'_, Arc>, ) -> Result<(), ResourceUsageCompatibilityError> { let current_simple = unsafe { current_state_set.simple.get_unchecked_mut(index) }; let current_state = if *current_simple == TextureUses::COMPLEX { diff --git a/wgpu/src/api/surface_texture.rs b/wgpu/src/api/surface_texture.rs index 9431683528..417ad56169 100644 --- a/wgpu/src/api/surface_texture.rs +++ b/wgpu/src/api/surface_texture.rs @@ -36,7 +36,6 @@ impl SurfaceTexture { self.presented = true; DynContext::surface_present( &*self.texture.context, - &self.texture.id, // This call to as_ref is essential because we want the DynContext implementation to see the inner // value of the Box (T::SurfaceOutputDetail), not the Box itself. self.detail.as_ref(), @@ -49,7 +48,6 @@ impl Drop for SurfaceTexture { if !self.presented && !thread::panicking() { DynContext::surface_texture_discard( &*self.texture.context, - &self.texture.id, // This call to as_ref is essential because we want the DynContext implementation to see the inner // value of the Box (T::SurfaceOutputDetail), not the Box itself. self.detail.as_ref(), diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 6865c439a1..702f170837 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -1495,15 +1495,11 @@ impl crate::context::Context for ContextWebGpu { ) } - fn surface_present(&self, _texture: &Self::TextureId, _detail: &Self::SurfaceOutputDetail) { + fn surface_present(&self, _detail: &Self::SurfaceOutputDetail) { // Swapchain is presented automatically } - fn surface_texture_discard( - &self, - _texture: &Self::TextureId, - _detail: &Self::SurfaceOutputDetail, - ) { + fn surface_texture_discard(&self, _detail: &Self::SurfaceOutputDetail) { // Can't really discard this on the Web } diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 32ee37183f..08acd37595 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -72,10 +72,7 @@ impl ContextWgpuCore { &self, hal_adapter: hal::ExposedAdapter, ) -> wgc::id::AdapterId { - unsafe { - self.0 - .create_adapter_from_hal::(hal_adapter.into(), None) - } + unsafe { self.0.create_adapter_from_hal(hal_adapter.into(), None) } } pub unsafe fn adapter_as_hal< @@ -112,7 +109,7 @@ impl ContextWgpuCore { log::error!("Feature 'trace' has been removed temporarily, see https://github.com/gfx-rs/wgpu/issues/5974"); } let (device_id, queue_id, error) = unsafe { - self.0.create_device_from_hal::( + self.0.create_device_from_hal( *adapter, hal_device.into(), &desc.map_label(|l| l.map(Borrowed)), @@ -146,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::(Box::new(hal_texture), device.id, &descriptor, None) + .create_texture_from_hal(Box::new(hal_texture), device.id, &descriptor, None) }; if let Some(cause) = error { self.handle_error( @@ -795,20 +792,14 @@ impl crate::Context for ContextWgpuCore { fn surface_get_current_texture( &self, surface: &Self::SurfaceId, - surface_data: &Self::SurfaceData, + _surface_data: &Self::SurfaceData, ) -> ( Option, Option, SurfaceStatus, Self::SurfaceOutputDetail, ) { - let device_id = surface_data - .configured_device - .lock() - .expect("Surface was not configured?"); - match wgc::gfx_select!( - device_id => self.0.surface_get_current_texture(*surface, None) - ) { + match self.0.surface_get_current_texture(*surface, None) { Ok(wgc::present::SurfaceOutput { status, texture_id }) => { let (id, data) = { ( @@ -833,19 +824,15 @@ impl crate::Context for ContextWgpuCore { } } - fn surface_present(&self, texture: &Self::TextureId, detail: &Self::SurfaceOutputDetail) { - match wgc::gfx_select!(texture => self.0.surface_present(detail.surface_id)) { + fn surface_present(&self, detail: &Self::SurfaceOutputDetail) { + match self.0.surface_present(detail.surface_id) { Ok(_status) => (), Err(err) => self.handle_error_fatal(err, "Surface::present"), } } - fn surface_texture_discard( - &self, - texture: &Self::TextureId, - detail: &Self::SurfaceOutputDetail, - ) { - match wgc::gfx_select!(texture => self.0.surface_texture_discard(detail.surface_id)) { + fn surface_texture_discard(&self, detail: &Self::SurfaceOutputDetail) { + match self.0.surface_texture_discard(detail.surface_id) { Ok(_status) => (), Err(err) => self.handle_error_fatal(err, "Surface::discard_texture"), } diff --git a/wgpu/src/context.rs b/wgpu/src/context.rs index 2c2c82c4bc..d28e4bc692 100644 --- a/wgpu/src/context.rs +++ b/wgpu/src/context.rs @@ -178,12 +178,8 @@ pub trait Context: Debug + WasmNotSendSync + Sized { SurfaceStatus, Self::SurfaceOutputDetail, ); - fn surface_present(&self, texture: &Self::TextureId, detail: &Self::SurfaceOutputDetail); - fn surface_texture_discard( - &self, - texture: &Self::TextureId, - detail: &Self::SurfaceOutputDetail, - ); + fn surface_present(&self, detail: &Self::SurfaceOutputDetail); + fn surface_texture_discard(&self, detail: &Self::SurfaceOutputDetail); fn device_features(&self, device: &Self::DeviceId, device_data: &Self::DeviceData) -> Features; fn device_limits(&self, device: &Self::DeviceId, device_data: &Self::DeviceData) -> Limits; @@ -1241,8 +1237,8 @@ pub(crate) trait DynContext: Debug + WasmNotSendSync { SurfaceStatus, Box, ); - fn surface_present(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync); - fn surface_texture_discard(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync); + fn surface_present(&self, detail: &dyn AnyWasmNotSendSync); + fn surface_texture_discard(&self, detail: &dyn AnyWasmNotSendSync); fn device_features(&self, device: &ObjectId, device_data: &crate::Data) -> Features; fn device_limits(&self, device: &ObjectId, device_data: &crate::Data) -> Limits; @@ -2204,14 +2200,12 @@ where ) } - fn surface_present(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync) { - let texture = ::from(*texture); - Context::surface_present(self, &texture, detail.downcast_ref().unwrap()) + fn surface_present(&self, detail: &dyn AnyWasmNotSendSync) { + Context::surface_present(self, detail.downcast_ref().unwrap()) } - fn surface_texture_discard(&self, texture: &ObjectId, detail: &dyn AnyWasmNotSendSync) { - let texture = ::from(*texture); - Context::surface_texture_discard(self, &texture, detail.downcast_ref().unwrap()) + fn surface_texture_discard(&self, detail: &dyn AnyWasmNotSendSync) { + Context::surface_texture_discard(self, detail.downcast_ref().unwrap()) } fn device_features(&self, device: &ObjectId, device_data: &crate::Data) -> Features { From ed1387df14457b102a858dc9b9a0549c8c35463e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 10 Aug 2024 12:36:04 +0200 Subject: [PATCH 48/53] ignore 'arc instead of rc' warnings on wasm --- wgpu-core/src/instance.rs | 1 - wgpu-core/src/lib.rs | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 8c7585be99..a71117cfe1 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -495,7 +495,6 @@ impl Global { surface_per_backend, }; - #[allow(clippy::arc_with_non_send_sync)] let id = self .surfaces .prepare(wgt::Backend::Empty, id_in) // No specific backend for Surface, since it's not specific. diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 179664490c..9b27d64a7b 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -62,6 +62,13 @@ the documentation for `wgpu-core` is empty unless built with unused_extern_crates, unused_qualifications )] +// We use `Arc` in wgpu-core, but on wasm (unless opted out via `fragile-send-sync-non-atomic-wasm`) +// wgpu-hal resources are not Send/Sync, causing a clippy warning for unnecessary `Arc`s. +// We could use `Rc`s in this case as recommended, but unless atomics are enabled +// this doesn't make a difference. +// Therefore, this is only really a concern for users targeting WebGL +// (the only reason to use wgpu-core on the web in the first place) that have atomics enabled. +#![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))] pub mod binding_model; pub mod command; From 0fd56eb4be9ec481636fbf5213a728d19a982408 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 10 Aug 2024 23:47:33 +0200 Subject: [PATCH 49/53] Handle webgl's `queue_copy_external_image_to_texture` --- wgpu-core/src/device/queue.rs | 36 +++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index deab6bff21..e516e0dac7 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1020,16 +1020,36 @@ impl Global { size: hal_copy_size, }; + let mut trackers = device.trackers.lock(); + let transitions = trackers + .textures + .set_single(&dst, selector, hal::TextureUses::COPY_DST); + + // `copy_external_image_to_texture` is exclusive to the WebGL backend. + // Don't go through the `DynCommandEncoder` abstraction and directly to the WebGL backend. + let encoder_webgl = encoder + .as_any_mut() + .downcast_mut::() + .unwrap(); + let dst_raw_webgl = dst_raw + .as_any() + .downcast_ref::() + .unwrap(); + let transitions_webgl = transitions.map(|pending| { + let dyn_transition = pending.into_hal(dst_raw); + hal::TextureBarrier { + texture: dst_raw_webgl, + range: dyn_transition.range, + usage: dyn_transition.usage, + } + }); + + use hal::CommandEncoder as _; unsafe { - let mut trackers = device.trackers.lock(); - let transitions = - trackers - .textures - .set_single(&dst, selector, hal::TextureUses::COPY_DST); - encoder.transition_textures(transitions.map(|pending| pending.into_hal(dst_raw))); - encoder.copy_external_image_to_texture( + encoder_webgl.transition_textures(transitions_webgl); + encoder_webgl.copy_external_image_to_texture( source, - dst_raw, + dst_raw_webgl, destination.premultiplied_alpha, iter::once(regions), ); From 844918ae65441bfab9953db1cad605240a10b5b0 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 6 Aug 2024 23:17:47 +0200 Subject: [PATCH 50/53] Remove `gfx_select`. --- deno_webgpu/binding.rs | 10 +- deno_webgpu/buffer.rs | 45 ++-- deno_webgpu/bundle.rs | 4 +- deno_webgpu/command_encoder.rs | 102 +++++---- deno_webgpu/lib.rs | 58 ++--- deno_webgpu/pipeline.rs | 28 +-- deno_webgpu/queue.rs | 22 +- deno_webgpu/sampler.rs | 4 +- deno_webgpu/shader.rs | 4 +- deno_webgpu/surface.rs | 4 +- deno_webgpu/texture.rs | 20 +- player/src/bin/play.rs | 159 +++++++------- player/tests/test.rs | 59 ++--- wgpu-core/src/hub.rs | 6 +- wgpu-core/src/lib.rs | 163 -------------- wgpu/src/backend/wgpu_core.rs | 383 +++++++++++++++------------------ 16 files changed, 431 insertions(+), 640 deletions(-) diff --git a/deno_webgpu/binding.rs b/deno_webgpu/binding.rs index 0efeb6716a..f1f3a80d35 100644 --- a/deno_webgpu/binding.rs +++ b/deno_webgpu/binding.rs @@ -21,7 +21,7 @@ impl Resource for WebGpuBindGroupLayout { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.bind_group_layout_drop(self.1)); + self.0.bind_group_layout_drop(self.1); } } @@ -35,7 +35,7 @@ impl Resource for WebGpuBindGroup { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.bind_group_drop(self.1)); + self.0.bind_group_drop(self.1); } } @@ -191,7 +191,7 @@ pub fn op_webgpu_create_bind_group_layout( entries: Cow::from(entries), }; - gfx_put!(device => instance.device_create_bind_group_layout( + gfx_put!(instance.device_create_bind_group_layout( device, &descriptor, None @@ -226,7 +226,7 @@ pub fn op_webgpu_create_pipeline_layout( push_constant_ranges: Default::default(), }; - gfx_put!(device => instance.device_create_pipeline_layout( + gfx_put!(instance.device_create_pipeline_layout( device, &descriptor, None @@ -305,7 +305,7 @@ pub fn op_webgpu_create_bind_group( entries: Cow::from(entries), }; - gfx_put!(device => instance.device_create_bind_group( + gfx_put!(instance.device_create_bind_group( device, &descriptor, None diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index 9a4900112a..08afcd133d 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -27,7 +27,7 @@ impl Resource for WebGpuBuffer { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.buffer_drop(self.1)); + self.0.buffer_drop(self.1); } } @@ -62,7 +62,7 @@ pub fn op_webgpu_create_buffer( mapped_at_creation, }; - gfx_put!(device => instance.device_create_buffer( + gfx_put!(instance.device_create_buffer( device, &descriptor, None @@ -97,20 +97,21 @@ pub async fn op_webgpu_buffer_get_map_async( }); // TODO(lucacasonato): error handling - let maybe_err = gfx_select!(buffer => instance.buffer_map_async( - buffer, - offset, - Some(size), - wgpu_core::resource::BufferMapOperation { - host: match mode { - 1 => wgpu_core::device::HostMap::Read, - 2 => wgpu_core::device::HostMap::Write, - _ => unreachable!(), + let maybe_err = instance + .buffer_map_async( + buffer, + offset, + Some(size), + wgpu_core::resource::BufferMapOperation { + host: match mode { + 1 => wgpu_core::device::HostMap::Read, + 2 => wgpu_core::device::HostMap::Write, + _ => unreachable!(), + }, + callback: Some(wgpu_core::resource::BufferMapCallback::from_rust(callback)), }, - callback: Some(wgpu_core::resource::BufferMapCallback::from_rust(callback)), - } - )) - .err(); + ) + .err(); if maybe_err.is_some() { return Ok(WebGpuResult::maybe_err(maybe_err)); @@ -124,7 +125,8 @@ pub async fn op_webgpu_buffer_get_map_async( { let state = state.borrow(); let instance = state.borrow::(); - gfx_select!(device => instance.device_poll(device, wgpu_types::Maintain::wait())) + instance + .device_poll(device, wgpu_types::Maintain::wait()) .unwrap(); } tokio::time::sleep(Duration::from_millis(10)).await; @@ -157,12 +159,9 @@ pub fn op_webgpu_buffer_get_mapped_range( let buffer_resource = state.resource_table.get::(buffer_rid)?; let buffer = buffer_resource.1; - let (slice_pointer, range_size) = gfx_select!(buffer => instance.buffer_get_mapped_range( - buffer, - offset, - size - )) - .map_err(|e| DomExceptionOperationError::new(&e.to_string()))?; + let (slice_pointer, range_size) = instance + .buffer_get_mapped_range(buffer, offset, size) + .map_err(|e| DomExceptionOperationError::new(&e.to_string()))?; // SAFETY: guarantee to be safe from wgpu let slice = @@ -199,5 +198,5 @@ pub fn op_webgpu_buffer_unmap( slice.copy_from_slice(buf); } - gfx_ok!(buffer => instance.buffer_unmap(buffer)) + gfx_ok!(instance.buffer_unmap(buffer)) } diff --git a/deno_webgpu/bundle.rs b/deno_webgpu/bundle.rs index dfe5ccf494..0d1421d202 100644 --- a/deno_webgpu/bundle.rs +++ b/deno_webgpu/bundle.rs @@ -30,7 +30,7 @@ impl Resource for WebGpuRenderBundle { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.render_bundle_drop(self.1)); + self.0.render_bundle_drop(self.1); } } @@ -108,7 +108,7 @@ pub fn op_webgpu_render_bundle_encoder_finish( .into_inner(); let instance = state.borrow::(); - gfx_put!(render_bundle_encoder.parent() => instance.render_bundle_encoder_finish( + gfx_put!(instance.render_bundle_encoder_finish( render_bundle_encoder, &wgpu_core::command::RenderBundleDescriptor { label: Some(label), diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index ba21bb05b5..84537f3c0b 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -23,7 +23,7 @@ impl Resource for WebGpuCommandEncoder { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.command_encoder_drop(self.1)); + self.0.command_encoder_drop(self.1); } } @@ -38,7 +38,7 @@ impl Resource for WebGpuCommandBuffer { fn close(self: Rc) { if let Some(id) = *self.1.borrow() { - gfx_select!(id => self.0.command_buffer_drop(id)); + self.0.command_buffer_drop(id); } } } @@ -58,7 +58,7 @@ pub fn op_webgpu_create_command_encoder( let descriptor = wgpu_types::CommandEncoderDescriptor { label: Some(label) }; - gfx_put!(device => instance.device_create_command_encoder( + gfx_put!(instance.device_create_command_encoder( device, &descriptor, None @@ -210,7 +210,8 @@ pub fn op_webgpu_command_encoder_begin_render_pass( occlusion_query_set: occlusion_query_set_resource, }; - let (render_pass, error) = gfx_select!(command_encoder => instance.command_encoder_create_render_pass_dyn(*command_encoder, &descriptor)); + let (render_pass, error) = + instance.command_encoder_create_render_pass_dyn(*command_encoder, &descriptor); let rid = state .resource_table .add(super::render_pass::WebGpuRenderPass(RefCell::new( @@ -262,7 +263,8 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( timestamp_writes: timestamp_writes.as_ref(), }; - let (compute_pass, error) = gfx_select!(command_encoder => instance.command_encoder_create_compute_pass_dyn(*command_encoder, &descriptor)); + let (compute_pass, error) = + instance.command_encoder_create_compute_pass_dyn(*command_encoder, &descriptor); let rid = state .resource_table .add(super::compute_pass::WebGpuComputePass(RefCell::new( @@ -297,13 +299,13 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_buffer( .get::(destination)?; let destination_buffer = destination_buffer_resource.1; - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_buffer( - command_encoder, - source_buffer, - source_offset, - destination_buffer, - destination_offset, - size + gfx_ok!(instance.command_encoder_copy_buffer_to_buffer( + command_encoder, + source_buffer, + source_offset, + destination_buffer, + destination_offset, + size )) } @@ -360,11 +362,11 @@ pub fn op_webgpu_command_encoder_copy_buffer_to_texture( origin: destination.origin, aspect: destination.aspect, }; - gfx_ok!(command_encoder => instance.command_encoder_copy_buffer_to_texture( - command_encoder, - &source, - &destination, - ©_size + gfx_ok!(instance.command_encoder_copy_buffer_to_texture( + command_encoder, + &source, + &destination, + ©_size )) } @@ -403,11 +405,11 @@ pub fn op_webgpu_command_encoder_copy_texture_to_buffer( rows_per_image: destination.rows_per_image, }, }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_buffer( - command_encoder, - &source, - &destination, - ©_size + gfx_ok!(instance.command_encoder_copy_texture_to_buffer( + command_encoder, + &source, + &destination, + ©_size )) } @@ -444,11 +446,11 @@ pub fn op_webgpu_command_encoder_copy_texture_to_texture( origin: destination.origin, aspect: destination.aspect, }; - gfx_ok!(command_encoder => instance.command_encoder_copy_texture_to_texture( - command_encoder, - &source, - &destination, - ©_size + gfx_ok!(instance.command_encoder_copy_texture_to_texture( + command_encoder, + &source, + &destination, + ©_size )) } @@ -470,11 +472,11 @@ pub fn op_webgpu_command_encoder_clear_buffer( .resource_table .get::(buffer_rid)?; - gfx_ok!(command_encoder => instance.command_encoder_clear_buffer( - command_encoder, - destination_resource.1, - offset, - Some(size) + gfx_ok!(instance.command_encoder_clear_buffer( + command_encoder, + destination_resource.1, + offset, + Some(size) )) } @@ -491,7 +493,7 @@ pub fn op_webgpu_command_encoder_push_debug_group( .get::(command_encoder_rid)?; let command_encoder = command_encoder_resource.1; - gfx_ok!(command_encoder => instance.command_encoder_push_debug_group(command_encoder, group_label)) + gfx_ok!(instance.command_encoder_push_debug_group(command_encoder, group_label)) } #[op2] @@ -506,7 +508,7 @@ pub fn op_webgpu_command_encoder_pop_debug_group( .get::(command_encoder_rid)?; let command_encoder = command_encoder_resource.1; - gfx_ok!(command_encoder => instance.command_encoder_pop_debug_group(command_encoder)) + gfx_ok!(instance.command_encoder_pop_debug_group(command_encoder)) } #[op2] @@ -522,10 +524,7 @@ pub fn op_webgpu_command_encoder_insert_debug_marker( .get::(command_encoder_rid)?; let command_encoder = command_encoder_resource.1; - gfx_ok!(command_encoder => instance.command_encoder_insert_debug_marker( - command_encoder, - marker_label - )) + gfx_ok!(instance.command_encoder_insert_debug_marker(command_encoder, marker_label)) } #[op2] @@ -545,10 +544,10 @@ pub fn op_webgpu_command_encoder_write_timestamp( .resource_table .get::(query_set)?; - gfx_ok!(command_encoder => instance.command_encoder_write_timestamp( - command_encoder, - query_set_resource.1, - query_index + gfx_ok!(instance.command_encoder_write_timestamp( + command_encoder, + query_set_resource.1, + query_index )) } @@ -575,13 +574,13 @@ pub fn op_webgpu_command_encoder_resolve_query_set( .resource_table .get::(destination)?; - gfx_ok!(command_encoder => instance.command_encoder_resolve_query_set( - command_encoder, - query_set_resource.1, - first_query, - query_count, - destination_resource.1, - destination_offset + gfx_ok!(instance.command_encoder_resolve_query_set( + command_encoder, + query_set_resource.1, + first_query, + query_count, + destination_resource.1, + destination_offset )) } @@ -600,10 +599,7 @@ pub fn op_webgpu_command_encoder_finish( let descriptor = wgpu_types::CommandBufferDescriptor { label: Some(label) }; - let (val, maybe_err) = gfx_select!(command_encoder => instance.command_encoder_finish( - command_encoder, - &descriptor - )); + let (val, maybe_err) = instance.command_encoder_finish(command_encoder, &descriptor); let rid = state.resource_table.add(WebGpuCommandBuffer( instance.clone(), diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 86120be713..c2dfb240fa 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -23,32 +23,17 @@ pub const UNSTABLE_FEATURE_NAME: &str = "webgpu"; #[macro_use] mod macros { - // TODO(#5124): remove this macro. - macro_rules! gfx_select { - ($id:expr => $p0:ident.$p1:tt.$method:ident $params:tt) => { - gfx_select!($id => {$p0.$p1}, $method $params) - }; - - ($id:expr => $p0:ident.$method:ident $params:tt) => { - gfx_select!($id => {$p0}, $method $params) - }; - - ($id:expr => {$($c:tt)*}, $method:ident $params:tt) => { - $($c)*.$method $params - }; - } - macro_rules! gfx_put { - ($id:expr => $global:ident.$method:ident( $($param:expr),* ) => $state:expr, $rc:expr) => {{ - let (val, maybe_err) = gfx_select!($id => $global.$method($($param),*)); + ($global:ident.$method:ident( $($param:expr),* ) => $state:expr, $rc:expr) => {{ + let (val, maybe_err) = $global.$method($($param),*); let rid = $state.resource_table.add($rc($global.clone(), val)); Ok(WebGpuResult::rid_err(rid, maybe_err)) }}; } macro_rules! gfx_ok { - ($id:expr => $global:ident.$method:ident( $($param:expr),* )) => {{ - let maybe_err = gfx_select!($id => $global.$method($($param),*)).err(); + ($global:ident.$method:ident( $($param:expr),* )) => {{ + let maybe_err = $global.$method($($param),*).err(); Ok(WebGpuResult::maybe_err(maybe_err)) }}; } @@ -78,7 +63,7 @@ impl Resource for WebGpuAdapter { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.adapter_drop(self.1)); + self.0.adapter_drop(self.1); } } @@ -89,7 +74,7 @@ impl Resource for WebGpuDevice { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.device_drop(self.1)); + self.0.device_drop(self.1); } } @@ -100,7 +85,7 @@ impl Resource for WebGpuQuerySet { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.query_set_drop(self.1)); + self.0.query_set_drop(self.1); } } @@ -429,9 +414,9 @@ pub fn op_webgpu_request_adapter( }) } }; - let adapter_features = gfx_select!(adapter => instance.adapter_features(adapter))?; + let adapter_features = instance.adapter_features(adapter)?; let features = deserialize_features(&adapter_features); - let adapter_limits = gfx_select!(adapter => instance.adapter_limits(adapter))?; + let adapter_limits = instance.adapter_limits(adapter)?; let instance = instance.clone(); @@ -664,21 +649,24 @@ pub fn op_webgpu_request_device( memory_hints: wgpu_types::MemoryHints::default(), }; - let (device, queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device( - adapter, - &descriptor, - std::env::var("DENO_WEBGPU_TRACE").ok().as_ref().map(std::path::Path::new), - None, - None - )); + let (device, queue, maybe_err) = instance.adapter_request_device( + adapter, + &descriptor, + std::env::var("DENO_WEBGPU_TRACE") + .ok() + .as_ref() + .map(std::path::Path::new), + None, + None, + ); adapter_resource.close(); if let Some(err) = maybe_err { return Err(DomExceptionOperationError::new(&err.to_string()).into()); } - let device_features = gfx_select!(device => instance.device_features(device))?; + let device_features = instance.device_features(device)?; let features = deserialize_features(&device_features); - let limits = gfx_select!(device => instance.device_limits(device))?; + let limits = instance.device_limits(device)?; let instance = instance.clone(); let instance2 = instance.clone(); @@ -717,7 +705,7 @@ pub fn op_webgpu_request_adapter_info( let adapter = adapter_resource.1; let instance = state.borrow::(); - let info = gfx_select!(adapter => instance.adapter_get_info(adapter))?; + let info = instance.adapter_get_info(adapter)?; adapter_resource.close(); Ok(GPUAdapterInfo { @@ -770,7 +758,7 @@ pub fn op_webgpu_create_query_set( count: args.count, }; - gfx_put!(device => instance.device_create_query_set( + gfx_put!(instance.device_create_query_set( device, &descriptor, None diff --git a/deno_webgpu/pipeline.rs b/deno_webgpu/pipeline.rs index 86d530332f..0ab3c40262 100644 --- a/deno_webgpu/pipeline.rs +++ b/deno_webgpu/pipeline.rs @@ -24,7 +24,7 @@ impl Resource for WebGpuPipelineLayout { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.pipeline_layout_drop(self.1)); + self.0.pipeline_layout_drop(self.1); } } @@ -38,7 +38,7 @@ impl Resource for WebGpuComputePipeline { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.compute_pipeline_drop(self.1)); + self.0.compute_pipeline_drop(self.1); } } @@ -52,7 +52,7 @@ impl Resource for WebGpuRenderPipeline { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.render_pipeline_drop(self.1)); + self.0.render_pipeline_drop(self.1); } } @@ -116,12 +116,8 @@ pub fn op_webgpu_create_compute_pipeline( cache: None, }; - let (compute_pipeline, maybe_err) = gfx_select!(device => instance.device_create_compute_pipeline( - device, - &descriptor, - None, - None, - )); + let (compute_pipeline, maybe_err) = + instance.device_create_compute_pipeline(device, &descriptor, None, None); let rid = state .resource_table @@ -150,7 +146,8 @@ pub fn op_webgpu_compute_pipeline_get_bind_group_layout( .get::(compute_pipeline_rid)?; let compute_pipeline = compute_pipeline_resource.1; - let (bind_group_layout, maybe_err) = gfx_select!(compute_pipeline => instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, None)); + let (bind_group_layout, maybe_err) = + instance.compute_pipeline_get_bind_group_layout(compute_pipeline, index, None); let rid = state .resource_table @@ -383,12 +380,8 @@ pub fn op_webgpu_create_render_pipeline( cache: None, }; - let (render_pipeline, maybe_err) = gfx_select!(device => instance.device_create_render_pipeline( - device, - &descriptor, - None, - None, - )); + let (render_pipeline, maybe_err) = + instance.device_create_render_pipeline(device, &descriptor, None, None); let rid = state .resource_table @@ -410,7 +403,8 @@ pub fn op_webgpu_render_pipeline_get_bind_group_layout( .get::(render_pipeline_rid)?; let render_pipeline = render_pipeline_resource.1; - let (bind_group_layout, maybe_err) = gfx_select!(render_pipeline => instance.render_pipeline_get_bind_group_layout(render_pipeline, index, None)); + let (bind_group_layout, maybe_err) = + instance.render_pipeline_get_bind_group_layout(render_pipeline, index, None); let rid = state .resource_table diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 2640134455..fdbf993f8c 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -20,7 +20,7 @@ impl Resource for WebGpuQueue { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.queue_drop(self.1)); + self.0.queue_drop(self.1); } } @@ -44,7 +44,7 @@ pub fn op_webgpu_queue_submit( }) .collect::, AnyError>>()?; - let maybe_err = gfx_select!(queue => instance.queue_submit(queue, &ids)).err(); + let maybe_err = instance.queue_submit(queue, &ids).err(); for rid in command_buffers { let resource = state.resource_table.take::(rid)?; @@ -95,13 +95,9 @@ pub fn op_webgpu_write_buffer( Some(size) => &buf[data_offset..(data_offset + size)], None => &buf[data_offset..], }; - let maybe_err = gfx_select!(queue => instance.queue_write_buffer( - queue, - buffer, - buffer_offset, - data - )) - .err(); + let maybe_err = instance + .queue_write_buffer(queue, buffer, buffer_offset, data) + .err(); Ok(WebGpuResult::maybe_err(maybe_err)) } @@ -131,11 +127,5 @@ pub fn op_webgpu_write_texture( }; let data_layout = data_layout.into(); - gfx_ok!(queue => instance.queue_write_texture( - queue, - &destination, - buf, - &data_layout, - &size - )) + gfx_ok!(instance.queue_write_texture(queue, &destination, buf, &data_layout, &size)) } diff --git a/deno_webgpu/sampler.rs b/deno_webgpu/sampler.rs index 822c4bda14..59b6f4e302 100644 --- a/deno_webgpu/sampler.rs +++ b/deno_webgpu/sampler.rs @@ -21,7 +21,7 @@ impl Resource for WebGpuSampler { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.sampler_drop(self.1)); + self.0.sampler_drop(self.1); } } @@ -71,7 +71,7 @@ pub fn op_webgpu_create_sampler( border_color: None, // native-only }; - gfx_put!(device => instance.device_create_sampler( + gfx_put!(instance.device_create_sampler( device, &descriptor, None diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index 17cde43936..4c7a30b2bd 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -20,7 +20,7 @@ impl Resource for WebGpuShaderModule { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.shader_module_drop(self.1)); + self.0.shader_module_drop(self.1); } } @@ -45,7 +45,7 @@ pub fn op_webgpu_create_shader_module( shader_bound_checks: wgpu_types::ShaderBoundChecks::default(), }; - gfx_put!(device => instance.device_create_shader_module( + gfx_put!(instance.device_create_shader_module( device, &descriptor, source, diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 9d9ba0d573..b48dbd2c8b 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -63,7 +63,7 @@ pub fn op_webgpu_surface_configure( desired_maximum_frame_latency: 2, }; - let err = gfx_select!(device => instance.surface_configure(surface, device, &conf)); + let err = instance.surface_configure(surface, device, &conf); Ok(WebGpuResult::maybe_err(err)) } @@ -79,7 +79,7 @@ pub fn op_webgpu_surface_get_current_texture( let surface_resource = state.resource_table.get::(surface_rid)?; let surface = surface_resource.1; - let output = gfx_select!(device => instance.surface_get_current_texture(surface, None))?; + let output = instance.surface_get_current_texture(surface, None)?; match output.status { SurfaceStatus::Good | SurfaceStatus::Suboptimal => { diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index 8acba24998..a432c7b627 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -24,7 +24,7 @@ impl Resource for WebGpuTexture { fn close(self: Rc) { if self.owned { let instance = &self.instance; - gfx_select!(self.id => instance.texture_drop(self.id)); + instance.texture_drop(self.id); } } } @@ -39,7 +39,7 @@ impl Resource for WebGpuTextureView { } fn close(self: Rc) { - gfx_select!(self.1 => self.0.texture_view_drop(self.1)).unwrap(); + self.0.texture_view_drop(self.1).unwrap(); } } @@ -80,11 +80,7 @@ pub fn op_webgpu_create_texture( view_formats: args.view_formats, }; - let (val, maybe_err) = gfx_select!(device => instance.device_create_texture( - device, - &descriptor, - None - )); + let (val, maybe_err) = instance.device_create_texture(device, &descriptor, None); let rid = state.resource_table.add(WebGpuTexture { instance: instance.clone(), @@ -125,9 +121,9 @@ pub fn op_webgpu_create_texture_view( range: args.range, }; - gfx_put!(texture => instance.texture_create_view( - texture, - &descriptor, - None - ) => state, WebGpuTextureView) + gfx_put!(instance.texture_create_view( + texture, + &descriptor, + None + ) => state, WebGpuTextureView) } diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index 8b6555369f..4726fe63a7 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -3,7 +3,7 @@ #[cfg(not(target_arch = "wasm32"))] fn main() { use player::GlobalPlay as _; - use wgc::{device::trace, gfx_select}; + use wgc::device::trace; use std::{ fs, @@ -78,17 +78,17 @@ fn main() { ) .expect("Unable to find an adapter for selected backend"); - let info = gfx_select!(adapter => global.adapter_get_info(adapter)).unwrap(); + let info = global.adapter_get_info(adapter).unwrap(); log::info!("Picked '{}'", info.name); let device_id = wgc::id::Id::zip(1, 0, backend); let queue_id = wgc::id::Id::zip(1, 0, backend); - let (_, _, error) = gfx_select!(adapter => global.adapter_request_device( + let (_, _, error) = global.adapter_request_device( adapter, &desc, None, Some(device_id), - Some(queue_id) - )); + Some(queue_id), + ); if let Some(e) = error { panic!("{:?}", e); } @@ -100,14 +100,14 @@ fn main() { log::info!("Executing actions"); #[cfg(not(feature = "winit"))] { - gfx_select!(device => global.device_start_capture(device)); + global.device_start_capture(device); while let Some(action) = actions.pop() { - gfx_select!(device => global.process(device, queue, action, &dir, &mut command_buffer_id_manager)); + global.process(device, queue, action, &dir, &mut command_buffer_id_manager); } - gfx_select!(device => global.device_stop_capture(device)); - gfx_select!(device => global.device_poll(device, wgt::Maintain::wait())).unwrap(); + global.device_stop_capture(device); + global.device_poll(device, wgt::Maintain::wait()).unwrap(); } #[cfg(feature = "winit")] { @@ -119,81 +119,92 @@ fn main() { let mut resize_config = None; let mut frame_count = 0; let mut done = false; - event_loop.run(move |event, target| { - target.set_control_flow(ControlFlow::Poll); - - match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::RedrawRequested if resize_config.is_none() => { - - match actions.pop() { - Some(trace::Action::ConfigureSurface(_device_id, config)) => { - log::info!("Configuring the surface"); - let current_size: (u32, u32) = window.inner_size().into(); - let size = (config.width, config.height); - if current_size != size { - let _ = window.request_inner_size(winit::dpi::PhysicalSize::new( - config.width, - config.height, - )); - resize_config = Some(config); - target.exit(); - } else { - let error = gfx_select!(device => global.surface_configure(surface, device, &config)); + event_loop + .run(move |event, target| { + target.set_control_flow(ControlFlow::Poll); + + match event { + Event::WindowEvent { event, .. } => match event { + WindowEvent::RedrawRequested if resize_config.is_none() => { + match actions.pop() { + Some(trace::Action::ConfigureSurface(_device_id, config)) => { + log::info!("Configuring the surface"); + let current_size: (u32, u32) = window.inner_size().into(); + let size = (config.width, config.height); + if current_size != size { + let _ = window.request_inner_size( + winit::dpi::PhysicalSize::new( + config.width, + config.height, + ), + ); + resize_config = Some(config); + target.exit(); + } else { + let error = + global.surface_configure(surface, device, &config); + if let Some(e) = error { + panic!("{:?}", e); + } + } + } + Some(trace::Action::Present(id)) => { + frame_count += 1; + log::debug!("Presenting frame {}", frame_count); + global.surface_present(id).unwrap(); + target.exit(); + } + Some(trace::Action::DiscardSurfaceTexture(id)) => { + log::debug!("Discarding frame {}", frame_count); + global.surface_texture_discard(id).unwrap(); + target.exit(); + } + Some(action) => { + global.process( + device, + queue, + action, + &dir, + &mut command_buffer_id_manager, + ); + } + None => { + if !done { + println!("Finished the end at frame {}", frame_count); + done = true; + } + target.exit(); + } + } + } + WindowEvent::Resized(_) => { + if let Some(config) = resize_config.take() { + let error = global.surface_configure(surface, device, &config); if let Some(e) = error { panic!("{:?}", e); } } } - Some(trace::Action::Present(id)) => { - frame_count += 1; - log::debug!("Presenting frame {}", frame_count); - gfx_select!(device => global.surface_present(id)).unwrap(); - target.exit(); - } - Some(trace::Action::DiscardSurfaceTexture(id)) => { - log::debug!("Discarding frame {}", frame_count); - gfx_select!(device => global.surface_texture_discard(id)).unwrap(); - target.exit(); - } - Some(action) => { - gfx_select!(device => global.process(device, queue, action, &dir, &mut command_buffer_id_manager)); - } - None => { - if !done { - println!("Finished the end at frame {}", frame_count); - done = true; - } - target.exit(); + WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + state: ElementState::Pressed, + .. + }, + .. } - } + | WindowEvent::CloseRequested => target.exit(), + _ => {} }, - WindowEvent::Resized(_) => { - if let Some(config) = resize_config.take() { - let error = gfx_select!(device => global.surface_configure(surface, device, &config)); - if let Some(e) = error { - panic!("{:?}", e); - } - } - } - WindowEvent::KeyboardInput { - event: KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - state: ElementState::Pressed, - .. - }, - .. + Event::LoopExiting => { + log::info!("Closing"); + global.device_poll(device, wgt::Maintain::wait()).unwrap(); } - | WindowEvent::CloseRequested => target.exit(), _ => {} - }, - Event::LoopExiting => { - log::info!("Closing"); - gfx_select!(device => global.device_poll(device, wgt::Maintain::wait())).unwrap(); } - _ => {} - } - }).unwrap(); + }) + .unwrap(); } } diff --git a/player/tests/test.rs b/player/tests/test.rs index f16e7fa32b..ee8e2ecc0d 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -107,7 +107,7 @@ impl Test<'_> { let backend = adapter.backend(); let device_id = wgc::id::Id::zip(test_num, 0, backend); let queue_id = wgc::id::Id::zip(test_num, 0, backend); - let (_, _, error) = wgc::gfx_select!(adapter => global.adapter_request_device( + let (_, _, error) = global.adapter_request_device( adapter, &wgt::DeviceDescriptor { label: None, @@ -117,8 +117,8 @@ impl Test<'_> { }, None, Some(device_id), - Some(queue_id) - )); + Some(queue_id), + ); if let Some(e) = error { panic!("{:?}", e); } @@ -126,35 +126,47 @@ impl Test<'_> { let mut command_buffer_id_manager = wgc::identity::IdentityManager::new(); println!("\t\t\tRunning..."); for action in self.actions { - wgc::gfx_select!(device_id => global.process(device_id, queue_id, action, dir, &mut command_buffer_id_manager)); + global.process( + device_id, + queue_id, + action, + dir, + &mut command_buffer_id_manager, + ); } println!("\t\t\tMapping..."); for expect in &self.expectations { let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend); - wgc::gfx_select!(device_id => global.buffer_map_async( - buffer, - expect.offset, - Some(expect.data.len() as u64), - wgc::resource::BufferMapOperation { - host: wgc::device::HostMap::Read, - callback: Some(wgc::resource::BufferMapCallback::from_rust( - Box::new(map_callback) - )), - } - )) - .unwrap(); + global + .buffer_map_async( + buffer, + expect.offset, + Some(expect.data.len() as u64), + wgc::resource::BufferMapOperation { + host: wgc::device::HostMap::Read, + callback: Some(wgc::resource::BufferMapCallback::from_rust(Box::new( + map_callback, + ))), + }, + ) + .unwrap(); } println!("\t\t\tWaiting..."); - wgc::gfx_select!(device_id => global.device_poll(device_id, wgt::Maintain::wait())) + global + .device_poll(device_id, wgt::Maintain::wait()) .unwrap(); for expect in self.expectations { println!("\t\t\tChecking {}", expect.name); let buffer = wgc::id::Id::zip(expect.buffer.index, expect.buffer.epoch, backend); - let (ptr, size) = - wgc::gfx_select!(device_id => global.buffer_get_mapped_range(buffer, expect.offset, Some(expect.data.len() as wgt::BufferAddress))) - .unwrap(); + let (ptr, size) = global + .buffer_get_mapped_range( + buffer, + expect.offset, + Some(expect.data.len() as wgt::BufferAddress), + ) + .unwrap(); let contents = unsafe { slice::from_raw_parts(ptr.as_ptr(), size as usize) }; let expected_data = match expect.data { ExpectedData::Raw(vec) => vec, @@ -231,11 +243,8 @@ impl Corpus { }; println!("\tBackend {:?}", backend); - let supported_features = - wgc::gfx_select!(adapter => global.adapter_features(adapter)).unwrap(); - let downlevel_caps = - wgc::gfx_select!(adapter => global.adapter_downlevel_capabilities(adapter)) - .unwrap(); + let supported_features = global.adapter_features(adapter).unwrap(); + let downlevel_caps = global.adapter_downlevel_capabilities(adapter).unwrap(); let test = Test::load(dir.join(test_path), adapter.backend()); if !supported_features.contains(test.features) { diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index cfdca16832..5cbb736301 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -10,10 +10,7 @@ of course `Debug`. [`id::BufferId`]: crate::id::BufferId Each `Id` contains not only an index for the resource it denotes but -also a Backend indicating which `wgpu` backend it belongs to. You -can use the [`gfx_select`] macro to dynamically dispatch on an id's -backend to a function specialized at compile time for a specific -backend. See that macro's documentation for details. +also a Backend indicating which `wgpu` backend it belongs to. `Id`s also incorporate a generation number, for additional validation. @@ -96,7 +93,6 @@ creation fails, the id supplied for that resource is marked to indicate as much, allowing subsequent operations using that id to be properly flagged as errors as well. -[`gfx_select`]: crate::gfx_select [`process`]: crate::identity::IdentityManager::process [`Id`]: crate::id::Id [wrapped in a mutex]: trait.IdentityHandler.html#impl-IdentityHandler%3CI%3E-for-Mutex%3CIdentityManager%3E diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 9b27d64a7b..ea7960fa57 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -153,169 +153,6 @@ If you are running this program on native and not in a browser and wish to work Adapter::downlevel_properties or Device::downlevel_properties to get a listing of the features the current \ platform supports."; -// #[cfg] attributes in exported macros are interesting! -// -// The #[cfg] conditions in a macro's expansion are evaluated using the -// configuration options (features, target architecture and os, etc.) in force -// where the macro is *used*, not where it is *defined*. That is, if crate A -// defines a macro like this: -// -// #[macro_export] -// macro_rules! if_bleep { -// { } => { -// #[cfg(feature = "bleep")] -// bleep(); -// } -// } -// -// and then crate B uses it like this: -// -// fn f() { -// if_bleep! { } -// } -// -// then it is crate B's `"bleep"` feature, not crate A's, that determines -// whether the macro expands to a function call or an empty statement. The -// entire configuration predicate is evaluated in the use's context, not the -// definition's. -// -// Since `wgpu-core` selects back ends using features, we need to make sure the -// arms of the `gfx_select!` macro are pruned according to `wgpu-core`'s -// features, not those of whatever crate happens to be using `gfx_select!`. This -// means we can't use `#[cfg]` attributes in `gfx_select!`s definition itself. -// Instead, for each backend, `gfx_select!` must use a macro whose definition is -// selected by `#[cfg]` in `wgpu-core`. The configuration predicate is still -// evaluated when the macro is used; we've just moved the `#[cfg]` into a macro -// used by `wgpu-core` itself. - -/// Define an exported macro named `$public` that expands to an expression if -/// the feature `$feature` is enabled, or to a panic otherwise. -/// -/// This is used in the definition of `gfx_select!`, to dispatch the -/// call to the appropriate backend, but panic if that backend was not -/// compiled in. -/// -/// For a call like this: -/// -/// ```ignore -/// define_backend_caller! { name, private, "feature" if cfg_condition } -/// ``` -/// -/// define a macro `name`, used like this: -/// -/// ```ignore -/// name!(expr) -/// ``` -/// -/// that expands to `expr` if `#[cfg(cfg_condition)]` is enabled, or a -/// panic otherwise. The panic message complains that `"feature"` is -/// not enabled. -/// -/// Because of odd technical limitations on exporting macros expanded -/// by other macros, you must supply both a public-facing name for the -/// macro and a private name, `$private`, which is never used -/// outside this macro. For details: -/// -macro_rules! define_backend_caller { - { $public:ident, $private:ident, $feature:literal if $cfg:meta } => { - #[cfg($cfg)] - #[macro_export] - macro_rules! $private { - ( $call:expr ) => ( $call ) - } - - #[cfg(not($cfg))] - #[macro_export] - macro_rules! $private { - ( $call:expr ) => ( - panic!("Identifier refers to disabled backend feature {:?}", $feature) - ) - } - - // See note about rust-lang#52234 above. - #[doc(hidden)] pub use $private as $public; - } -} - -// Define a macro for each `gfx_select!` match arm. For example, -// -// gfx_if_vulkan!(expr) -// -// expands to `expr` if the `"vulkan"` feature is enabled, or to a panic -// otherwise. -define_backend_caller! { gfx_if_vulkan, gfx_if_vulkan_hidden, "vulkan" if all(feature = "vulkan", not(target_arch = "wasm32")) } -define_backend_caller! { gfx_if_metal, gfx_if_metal_hidden, "metal" if all(feature = "metal", any(target_os = "macos", target_os = "ios")) } -define_backend_caller! { gfx_if_dx12, gfx_if_dx12_hidden, "dx12" if all(feature = "dx12", windows) } -define_backend_caller! { gfx_if_gles, gfx_if_gles_hidden, "gles" if feature = "gles" } -define_backend_caller! { gfx_if_empty, gfx_if_empty_hidden, "empty" if all( - not(any(feature = "metal", feature = "vulkan", feature = "gles")), - any(target_os = "macos", target_os = "ios"), -) } - -/// Dispatch on an [`Id`]'s backend to a backend-generic method. -/// -/// Uses of this macro have the form: -/// -/// ```ignore -/// -/// gfx_select!(id => value.method(args...)) -/// -/// ``` -/// -/// This expands to an expression that calls `value.method::(args...)` for -/// the backend `A` selected by `id`. The expansion matches on `id.backend()`, -/// with an arm for each backend type in [`wgpu_types::Backend`] which calls the -/// specialization of `method` for the given backend. This allows resource -/// identifiers to select backends dynamically, even though many `wgpu_core` -/// methods are compiled and optimized for a specific back end. -/// -/// This macro is typically used to call methods on [`wgpu_core::global::Global`], -/// many of which take a single `hal::Api` type parameter. For example, to -/// create a new buffer on the device indicated by `device_id`, one would say: -/// -/// ```ignore -/// gfx_select!(device_id => global.device_create_buffer(device_id, ...)) -/// ``` -/// -/// where the `device_create_buffer` method is defined like this: -/// -/// ```ignore -/// impl Global { -/// pub fn device_create_buffer(&self, ...) -> ... -/// { ... } -/// } -/// ``` -/// -/// That `gfx_select!` call uses `device_id`'s backend to select the right -/// backend type `A` for a call to `Global::device_create_buffer`. -/// -/// However, there's nothing about this macro that is specific to `hub::Global`. -/// For example, Firefox's embedding of `wgpu_core` defines its own types with -/// methods that take `hal::Api` type parameters. Firefox uses `gfx_select!` to -/// dynamically dispatch to the right specialization based on the resource's id. -/// -/// [`wgpu_types::Backend`]: wgt::Backend -/// [`wgpu_core::global::Global`]: crate::global::Global -/// [`Id`]: id::Id -// -// TODO(#5124): Remove this altogether. -#[macro_export] -macro_rules! gfx_select { - // Simple two-component expression, like `self.0.method(..)`. - ($id:expr => $c0:ident.$c1:tt.$method:ident $params:tt) => { - $crate::gfx_select!($id => {$c0.$c1}, $method $params) - }; - - // Simple identifier-only expression, like `global.method(..)`. - ($id:expr => $c0:ident.$method:ident $params:tt) => { - $crate::gfx_select!($id => {$c0}, $method $params) - }; - - ($id:expr => {$($c:tt)*}, $method:ident $params:tt) => { - $($c)*.$method $params - }; -} - #[cfg(feature = "api_log_info")] macro_rules! api_log { ($($arg:tt)+) => (log::info!($($arg)+)) diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 08acd37595..30a8743fb2 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -25,8 +25,8 @@ use std::{ sync::Arc, }; use wgc::{ - command::bundle_ffi::*, device::DeviceLostClosure, gfx_select, id::CommandEncoderId, - id::TextureViewId, pipeline::CreateShaderModuleError, + command::bundle_ffi::*, device::DeviceLostClosure, id::CommandEncoderId, id::TextureViewId, + pipeline::CreateShaderModuleError, }; use wgt::WasmNotSendSync; @@ -646,13 +646,13 @@ impl crate::Context for ContextWgpuCore { if trace_dir.is_some() { log::error!("Feature 'trace' has been removed temporarily, see https://github.com/gfx-rs/wgpu/issues/5974"); } - let (device_id, queue_id, error) = wgc::gfx_select!(*adapter => self.0.adapter_request_device( + let (device_id, queue_id, error) = self.0.adapter_request_device( *adapter, &desc.map_label(|l| l.map(Borrowed)), None, None, - None - )); + None, + ); if let Some(err) = error { return ready(Err(err.into())); } @@ -683,7 +683,7 @@ impl crate::Context for ContextWgpuCore { surface: &Self::SurfaceId, _surface_data: &Self::SurfaceData, ) -> bool { - match wgc::gfx_select!(adapter => self.0.adapter_is_surface_supported(*adapter, *surface)) { + match self.0.adapter_is_surface_supported(*adapter, *surface) { Ok(result) => result, Err(err) => self.handle_error_fatal(err, "Adapter::is_surface_supported"), } @@ -694,7 +694,7 @@ impl crate::Context for ContextWgpuCore { adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData, ) -> Features { - match wgc::gfx_select!(*adapter => self.0.adapter_features(*adapter)) { + match self.0.adapter_features(*adapter) { Ok(features) => features, Err(err) => self.handle_error_fatal(err, "Adapter::features"), } @@ -705,7 +705,7 @@ impl crate::Context for ContextWgpuCore { adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData, ) -> Limits { - match wgc::gfx_select!(*adapter => self.0.adapter_limits(*adapter)) { + match self.0.adapter_limits(*adapter) { Ok(limits) => limits, Err(err) => self.handle_error_fatal(err, "Adapter::limits"), } @@ -716,7 +716,7 @@ impl crate::Context for ContextWgpuCore { adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData, ) -> DownlevelCapabilities { - match wgc::gfx_select!(*adapter => self.0.adapter_downlevel_capabilities(*adapter)) { + match self.0.adapter_downlevel_capabilities(*adapter) { Ok(downlevel) => downlevel, Err(err) => self.handle_error_fatal(err, "Adapter::downlevel_properties"), } @@ -727,7 +727,7 @@ impl crate::Context for ContextWgpuCore { adapter: &wgc::id::AdapterId, _adapter_data: &Self::AdapterData, ) -> AdapterInfo { - match wgc::gfx_select!(*adapter => self.0.adapter_get_info(*adapter)) { + match self.0.adapter_get_info(*adapter) { Ok(info) => info, Err(err) => self.handle_error_fatal(err, "Adapter::get_info"), } @@ -739,8 +739,7 @@ impl crate::Context for ContextWgpuCore { _adapter_data: &Self::AdapterData, format: wgt::TextureFormat, ) -> wgt::TextureFormatFeatures { - match wgc::gfx_select!(*adapter => self.0.adapter_get_texture_format_features(*adapter, format)) - { + match self.0.adapter_get_texture_format_features(*adapter, format) { Ok(info) => info, Err(err) => self.handle_error_fatal(err, "Adapter::get_texture_format_features"), } @@ -751,7 +750,7 @@ impl crate::Context for ContextWgpuCore { adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData, ) -> wgt::PresentationTimestamp { - match wgc::gfx_select!(*adapter => self.0.adapter_get_presentation_timestamp(*adapter)) { + match self.0.adapter_get_presentation_timestamp(*adapter) { Ok(timestamp) => timestamp, Err(err) => self.handle_error_fatal(err, "Adapter::correlate_presentation_timestamp"), } @@ -764,7 +763,7 @@ impl crate::Context for ContextWgpuCore { adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData, ) -> wgt::SurfaceCapabilities { - match wgc::gfx_select!(adapter => self.0.surface_get_capabilities(*surface, *adapter)) { + match self.0.surface_get_capabilities(*surface, *adapter) { Ok(caps) => caps, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => { wgt::SurfaceCapabilities::default() @@ -781,7 +780,7 @@ impl crate::Context for ContextWgpuCore { _device_data: &Self::DeviceData, config: &crate::SurfaceConfiguration, ) { - let error = wgc::gfx_select!(device => self.0.surface_configure(*surface, *device, config)); + let error = self.0.surface_configure(*surface, *device, config); if let Some(e) = error { self.handle_error_fatal(e, "Surface::configure"); } else { @@ -843,14 +842,14 @@ impl crate::Context for ContextWgpuCore { device: &Self::DeviceId, _device_data: &Self::DeviceData, ) -> Features { - match wgc::gfx_select!(device => self.0.device_features(*device)) { + match self.0.device_features(*device) { Ok(features) => features, Err(err) => self.handle_error_fatal(err, "Device::features"), } } fn device_limits(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) -> Limits { - match wgc::gfx_select!(device => self.0.device_limits(*device)) { + match self.0.device_limits(*device) { Ok(limits) => limits, Err(err) => self.handle_error_fatal(err, "Device::limits"), } @@ -861,7 +860,7 @@ impl crate::Context for ContextWgpuCore { device: &Self::DeviceId, _device_data: &Self::DeviceData, ) -> DownlevelCapabilities { - match wgc::gfx_select!(device => self.0.device_downlevel_properties(*device)) { + match self.0.device_downlevel_properties(*device) { Ok(limits) => limits, Err(err) => self.handle_error_fatal(err, "Device::downlevel_properties"), } @@ -913,9 +912,9 @@ impl crate::Context for ContextWgpuCore { ShaderSource::Naga(module) => wgc::pipeline::ShaderModuleSource::Naga(module), ShaderSource::Dummy(_) => panic!("found `ShaderSource::Dummy`"), }; - let (id, error) = wgc::gfx_select!( - device => self.0.device_create_shader_module(*device, &descriptor, source, None) - ); + let (id, error) = self + .0 + .device_create_shader_module(*device, &descriptor, source, None); let compilation_info = match error { Some(cause) => { self.handle_error( @@ -944,9 +943,14 @@ impl crate::Context for ContextWgpuCore { // runtime checks shader_bound_checks: unsafe { wgt::ShaderBoundChecks::unchecked() }, }; - let (id, error) = wgc::gfx_select!( - device => self.0.device_create_shader_module_spirv(*device, &descriptor, Borrowed(&desc.source), None) - ); + let (id, error) = unsafe { + self.0.device_create_shader_module_spirv( + *device, + &descriptor, + Borrowed(&desc.source), + None, + ) + }; let compilation_info = match error { Some(cause) => { self.handle_error( @@ -972,9 +976,9 @@ impl crate::Context for ContextWgpuCore { label: desc.label.map(Borrowed), entries: Borrowed(desc.entries), }; - let (id, error) = wgc::gfx_select!( - device => self.0.device_create_bind_group_layout(*device, &descriptor, None) - ); + let (id, error) = self + .0 + .device_create_bind_group_layout(*device, &descriptor, None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1083,11 +1087,7 @@ impl crate::Context for ContextWgpuCore { entries: Borrowed(&entries), }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_bind_group( - *device, - &descriptor, - None - )); + let (id, error) = self.0.device_create_bind_group(*device, &descriptor, None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1124,11 +1124,9 @@ impl crate::Context for ContextWgpuCore { push_constant_ranges: Borrowed(desc.push_constant_ranges), }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_pipeline_layout( - *device, - &descriptor, - None - )); + let (id, error) = self + .0 + .device_create_pipeline_layout(*device, &descriptor, None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1191,12 +1189,9 @@ impl crate::Context for ContextWgpuCore { cache: desc.cache.map(|c| c.id.into()), }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_render_pipeline( - *device, - &descriptor, - None, - None, - )); + let (id, error) = self + .0 + .device_create_render_pipeline(*device, &descriptor, None, None); if let Some(cause) = error { if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause { log::error!("Shader translation error for stage {:?}: {}", stage, error); @@ -1233,12 +1228,9 @@ impl crate::Context for ContextWgpuCore { cache: desc.cache.map(|c| c.id.into()), }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_compute_pipeline( - *device, - &descriptor, - None, - None, - )); + let (id, error) = self + .0 + .device_create_compute_pipeline(*device, &descriptor, None, None); if let Some(cause) = error { if let wgc::pipeline::CreateComputePipelineError::Internal(ref error) = cause { log::error!( @@ -1271,11 +1263,10 @@ impl crate::Context for ContextWgpuCore { data: desc.data.map(Borrowed), fallback: desc.fallback, }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_pipeline_cache( - *device, - &descriptor, - None - )); + let (id, error) = unsafe { + self.0 + .device_create_pipeline_cache(*device, &descriptor, None) + }; if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1293,11 +1284,9 @@ impl crate::Context for ContextWgpuCore { device_data: &Self::DeviceData, desc: &crate::BufferDescriptor<'_>, ) -> (Self::BufferId, Self::BufferData) { - let (id, error) = wgc::gfx_select!(device => self.0.device_create_buffer( - *device, - &desc.map_label(|l| l.map(Borrowed)), - None - )); + let (id, error) = + self.0 + .device_create_buffer(*device, &desc.map_label(|l| l.map(Borrowed)), None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1320,11 +1309,7 @@ impl crate::Context for ContextWgpuCore { desc: &TextureDescriptor<'_>, ) -> (Self::TextureId, Self::TextureData) { let wgt_desc = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec()); - let (id, error) = wgc::gfx_select!(device => self.0.device_create_texture( - *device, - &wgt_desc, - None - )); + let (id, error) = self.0.device_create_texture(*device, &wgt_desc, None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1364,11 +1349,7 @@ impl crate::Context for ContextWgpuCore { border_color: desc.border_color, }; - let (id, error) = wgc::gfx_select!(device => self.0.device_create_sampler( - *device, - &descriptor, - None - )); + let (id, error) = self.0.device_create_sampler(*device, &descriptor, None); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1385,11 +1366,9 @@ impl crate::Context for ContextWgpuCore { device_data: &Self::DeviceData, desc: &wgt::QuerySetDescriptor>, ) -> (Self::QuerySetId, Self::QuerySetData) { - let (id, error) = wgc::gfx_select!(device => self.0.device_create_query_set( - *device, - &desc.map_label(|l| l.map(Borrowed)), - None - )); + let (id, error) = + self.0 + .device_create_query_set(*device, &desc.map_label(|l| l.map(Borrowed)), None); if let Some(cause) = error { self.handle_error_nolabel(&device_data.error_sink, cause, "Device::create_query_set"); } @@ -1401,11 +1380,11 @@ impl crate::Context for ContextWgpuCore { device_data: &Self::DeviceData, desc: &CommandEncoderDescriptor<'_>, ) -> (Self::CommandEncoderId, Self::CommandEncoderData) { - let (id, error) = wgc::gfx_select!(device => self.0.device_create_command_encoder( + let (id, error) = self.0.device_create_command_encoder( *device, &desc.map_label(|l| l.map(Borrowed)), - None - )); + None, + ); if let Some(cause) = error { self.handle_error( &device_data.error_sink, @@ -1442,7 +1421,7 @@ impl crate::Context for ContextWgpuCore { } #[doc(hidden)] fn device_make_invalid(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { - wgc::gfx_select!(device => self.0.device_make_invalid(*device)); + self.0.device_make_invalid(*device); } #[cfg_attr(not(any(native, Emscripten)), allow(unused))] fn device_drop(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { @@ -1450,13 +1429,13 @@ impl crate::Context for ContextWgpuCore { { // Call device_poll, but don't check for errors. We have to use its // return value, but we just drop it. - let _ = wgc::gfx_select!(device => self.0.device_poll(*device, wgt::Maintain::wait())); - wgc::gfx_select!(device => self.0.device_drop(*device)); + let _ = self.0.device_poll(*device, wgt::Maintain::wait()); + self.0.device_drop(*device); } } #[cfg_attr(target_arch = "wasm32", allow(unused))] fn queue_drop(&self, queue: &Self::QueueId, _device_data: &Self::QueueData) { - wgc::gfx_select!(queue => self.0.queue_drop(*queue)); + self.0.queue_drop(*queue); } fn device_set_device_lost_callback( &self, @@ -1465,10 +1444,11 @@ impl crate::Context for ContextWgpuCore { device_lost_callback: crate::context::DeviceLostCallback, ) { let device_lost_closure = DeviceLostClosure::from_rust(device_lost_callback); - wgc::gfx_select!(device => self.0.device_set_device_lost_closure(*device, device_lost_closure)); + self.0 + .device_set_device_lost_closure(*device, device_lost_closure); } fn device_destroy(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { - wgc::gfx_select!(device => self.0.device_destroy(*device)); + self.0.device_destroy(*device); } fn device_mark_lost( &self, @@ -1478,7 +1458,7 @@ impl crate::Context for ContextWgpuCore { ) { // We do not provide a reason to device_lose, because all reasons other than // destroyed (which this is not) are "unknown". - wgc::gfx_select!(device => self.0.device_mark_lost(*device, message)); + self.0.device_mark_lost(*device, message); } fn device_poll( &self, @@ -1487,10 +1467,7 @@ impl crate::Context for ContextWgpuCore { maintain: crate::Maintain, ) -> wgt::MaintainResult { let maintain_inner = maintain.map_index(|i| *i.0.as_ref().downcast_ref().unwrap()); - match wgc::gfx_select!(device => self.0.device_poll( - *device, - maintain_inner - )) { + match self.0.device_poll(*device, maintain_inner) { Ok(done) => match done { true => wgt::MaintainResult::SubmissionQueueEmpty, false => wgt::MaintainResult::Ok, @@ -1550,8 +1527,12 @@ impl crate::Context for ContextWgpuCore { ))), }; - match wgc::gfx_select!(buffer => self.0.buffer_map_async(*buffer, range.start, Some(range.end-range.start), operation)) - { + match self.0.buffer_map_async( + *buffer, + range.start, + Some(range.end - range.start), + operation, + ) { Ok(()) => (), Err(cause) => { self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::map_async") @@ -1565,11 +1546,10 @@ impl crate::Context for ContextWgpuCore { sub_range: Range, ) -> Box { let size = sub_range.end - sub_range.start; - match wgc::gfx_select!(buffer => self.0.buffer_get_mapped_range( - *buffer, - sub_range.start, - Some(size) - )) { + match self + .0 + .buffer_get_mapped_range(*buffer, sub_range.start, Some(size)) + { Ok((ptr, size)) => Box::new(BufferMappedRange { ptr, size: size as usize, @@ -1579,7 +1559,7 @@ impl crate::Context for ContextWgpuCore { } fn buffer_unmap(&self, buffer: &Self::BufferId, buffer_data: &Self::BufferData) { - match wgc::gfx_select!(buffer => self.0.buffer_unmap(*buffer)) { + match self.0.buffer_unmap(*buffer) { Ok(()) => (), Err(cause) => { self.handle_error_nolabel(&buffer_data.error_sink, cause, "Buffer::buffer_unmap") @@ -1613,9 +1593,7 @@ impl crate::Context for ContextWgpuCore { array_layer_count: desc.array_layer_count, }, }; - let (id, error) = wgc::gfx_select!( - texture => self.0.texture_create_view(*texture, &descriptor, None) - ); + let (id, error) = self.0.texture_create_view(*texture, &descriptor, None); if let Some(cause) = error { self.handle_error( &texture_data.error_sink, @@ -1632,25 +1610,25 @@ impl crate::Context for ContextWgpuCore { } fn adapter_drop(&self, adapter: &Self::AdapterId, _adapter_data: &Self::AdapterData) { - wgc::gfx_select!(*adapter => self.0.adapter_drop(*adapter)) + self.0.adapter_drop(*adapter) } fn buffer_destroy(&self, buffer: &Self::BufferId, _buffer_data: &Self::BufferData) { // Per spec, no error to report. Even calling destroy multiple times is valid. - let _ = wgc::gfx_select!(buffer => self.0.buffer_destroy(*buffer)); + let _ = self.0.buffer_destroy(*buffer); } fn buffer_drop(&self, buffer: &Self::BufferId, _buffer_data: &Self::BufferData) { - wgc::gfx_select!(buffer => self.0.buffer_drop(*buffer)) + self.0.buffer_drop(*buffer) } fn texture_destroy(&self, texture: &Self::TextureId, _texture_data: &Self::TextureData) { // Per spec, no error to report. Even calling destroy multiple times is valid. - let _ = wgc::gfx_select!(texture => self.0.texture_destroy(*texture)); + let _ = self.0.texture_destroy(*texture); } fn texture_drop(&self, texture: &Self::TextureId, _texture_data: &Self::TextureData) { - wgc::gfx_select!(texture => self.0.texture_drop(*texture)) + self.0.texture_drop(*texture) } fn texture_view_drop( @@ -1658,15 +1636,15 @@ impl crate::Context for ContextWgpuCore { texture_view: &Self::TextureViewId, __texture_view_data: &Self::TextureViewData, ) { - let _ = wgc::gfx_select!(*texture_view => self.0.texture_view_drop(*texture_view)); + let _ = self.0.texture_view_drop(*texture_view); } fn sampler_drop(&self, sampler: &Self::SamplerId, _sampler_data: &Self::SamplerData) { - wgc::gfx_select!(*sampler => self.0.sampler_drop(*sampler)) + self.0.sampler_drop(*sampler) } fn query_set_drop(&self, query_set: &Self::QuerySetId, _query_set_data: &Self::QuerySetData) { - wgc::gfx_select!(*query_set => self.0.query_set_drop(*query_set)) + self.0.query_set_drop(*query_set) } fn bind_group_drop( @@ -1674,7 +1652,7 @@ impl crate::Context for ContextWgpuCore { bind_group: &Self::BindGroupId, _bind_group_data: &Self::BindGroupData, ) { - wgc::gfx_select!(*bind_group => self.0.bind_group_drop(*bind_group)) + self.0.bind_group_drop(*bind_group) } fn bind_group_layout_drop( @@ -1682,7 +1660,7 @@ impl crate::Context for ContextWgpuCore { bind_group_layout: &Self::BindGroupLayoutId, _bind_group_layout_data: &Self::BindGroupLayoutData, ) { - wgc::gfx_select!(*bind_group_layout => self.0.bind_group_layout_drop(*bind_group_layout)) + self.0.bind_group_layout_drop(*bind_group_layout) } fn pipeline_layout_drop( @@ -1690,14 +1668,14 @@ impl crate::Context for ContextWgpuCore { pipeline_layout: &Self::PipelineLayoutId, _pipeline_layout_data: &Self::PipelineLayoutData, ) { - wgc::gfx_select!(*pipeline_layout => self.0.pipeline_layout_drop(*pipeline_layout)) + self.0.pipeline_layout_drop(*pipeline_layout) } fn shader_module_drop( &self, shader_module: &Self::ShaderModuleId, _shader_module_data: &Self::ShaderModuleData, ) { - wgc::gfx_select!(*shader_module => self.0.shader_module_drop(*shader_module)) + self.0.shader_module_drop(*shader_module) } fn command_encoder_drop( &self, @@ -1705,7 +1683,7 @@ impl crate::Context for ContextWgpuCore { command_encoder_data: &Self::CommandEncoderData, ) { if command_encoder_data.open { - wgc::gfx_select!(command_encoder => self.0.command_encoder_drop(*command_encoder)) + self.0.command_encoder_drop(*command_encoder) } } @@ -1714,7 +1692,7 @@ impl crate::Context for ContextWgpuCore { command_buffer: &Self::CommandBufferId, _command_buffer_data: &Self::CommandBufferData, ) { - wgc::gfx_select!(*command_buffer => self.0.command_buffer_drop(*command_buffer)) + self.0.command_buffer_drop(*command_buffer) } fn render_bundle_drop( @@ -1722,7 +1700,7 @@ impl crate::Context for ContextWgpuCore { render_bundle: &Self::RenderBundleId, _render_bundle_data: &Self::RenderBundleData, ) { - wgc::gfx_select!(*render_bundle => self.0.render_bundle_drop(*render_bundle)) + self.0.render_bundle_drop(*render_bundle) } fn compute_pipeline_drop( @@ -1730,7 +1708,7 @@ impl crate::Context for ContextWgpuCore { pipeline: &Self::ComputePipelineId, _pipeline_data: &Self::ComputePipelineData, ) { - wgc::gfx_select!(*pipeline => self.0.compute_pipeline_drop(*pipeline)) + self.0.compute_pipeline_drop(*pipeline) } fn render_pipeline_drop( @@ -1738,7 +1716,7 @@ impl crate::Context for ContextWgpuCore { pipeline: &Self::RenderPipelineId, _pipeline_data: &Self::RenderPipelineData, ) { - wgc::gfx_select!(*pipeline => self.0.render_pipeline_drop(*pipeline)) + self.0.render_pipeline_drop(*pipeline) } fn pipeline_cache_drop( @@ -1746,7 +1724,7 @@ impl crate::Context for ContextWgpuCore { cache: &Self::PipelineCacheId, _cache_data: &Self::PipelineCacheData, ) { - wgc::gfx_select!(*cache => self.0.pipeline_cache_drop(*cache)) + self.0.pipeline_cache_drop(*cache) } fn compute_pipeline_get_bind_group_layout( @@ -1755,7 +1733,9 @@ impl crate::Context for ContextWgpuCore { _pipeline_data: &Self::ComputePipelineData, index: u32, ) -> (Self::BindGroupLayoutId, Self::BindGroupLayoutData) { - let (id, error) = wgc::gfx_select!(*pipeline => self.0.compute_pipeline_get_bind_group_layout(*pipeline, index, None)); + let (id, error) = self + .0 + .compute_pipeline_get_bind_group_layout(*pipeline, index, None); if let Some(err) = error { panic!("Error reflecting bind group {index}: {err}"); } @@ -1768,7 +1748,9 @@ impl crate::Context for ContextWgpuCore { _pipeline_data: &Self::RenderPipelineData, index: u32, ) -> (Self::BindGroupLayoutId, Self::BindGroupLayoutData) { - let (id, error) = wgc::gfx_select!(*pipeline => self.0.render_pipeline_get_bind_group_layout(*pipeline, index, None)); + let (id, error) = self + .0 + .render_pipeline_get_bind_group_layout(*pipeline, index, None); if let Some(err) = error { panic!("Error reflecting bind group {index}: {err}"); } @@ -1787,14 +1769,14 @@ impl crate::Context for ContextWgpuCore { destination_offset: wgt::BufferAddress, copy_size: wgt::BufferAddress, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_copy_buffer_to_buffer( + if let Err(cause) = self.0.command_encoder_copy_buffer_to_buffer( *encoder, *source, source_offset, *destination, destination_offset, - copy_size - )) { + copy_size, + ) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -1811,12 +1793,12 @@ impl crate::Context for ContextWgpuCore { destination: crate::ImageCopyTexture<'_>, copy_size: wgt::Extent3d, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_copy_buffer_to_texture( + if let Err(cause) = self.0.command_encoder_copy_buffer_to_texture( *encoder, &map_buffer_copy_view(source), &map_texture_copy_view(destination), - ©_size - )) { + ©_size, + ) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -1833,12 +1815,12 @@ impl crate::Context for ContextWgpuCore { destination: crate::ImageCopyBuffer<'_>, copy_size: wgt::Extent3d, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_copy_texture_to_buffer( + if let Err(cause) = self.0.command_encoder_copy_texture_to_buffer( *encoder, &map_texture_copy_view(source), &map_buffer_copy_view(destination), - ©_size - )) { + ©_size, + ) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -1855,12 +1837,12 @@ impl crate::Context for ContextWgpuCore { destination: crate::ImageCopyTexture<'_>, copy_size: wgt::Extent3d, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_copy_texture_to_texture( + if let Err(cause) = self.0.command_encoder_copy_texture_to_texture( *encoder, &map_texture_copy_view(source), &map_texture_copy_view(destination), - ©_size - )) { + ©_size, + ) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -1884,10 +1866,13 @@ impl crate::Context for ContextWgpuCore { end_of_pass_write_index: tw.end_of_pass_write_index, }); - let (pass, err) = gfx_select!(encoder => self.0.command_encoder_create_compute_pass_dyn(*encoder, &wgc::command::ComputePassDescriptor { - label: desc.label.map(Borrowed), - timestamp_writes: timestamp_writes.as_ref(), - })); + let (pass, err) = self.0.command_encoder_create_compute_pass_dyn( + *encoder, + &wgc::command::ComputePassDescriptor { + label: desc.label.map(Borrowed), + timestamp_writes: timestamp_writes.as_ref(), + }, + ); if let Some(cause) = err { self.handle_error( @@ -1943,13 +1928,18 @@ impl crate::Context for ContextWgpuCore { end_of_pass_write_index: tw.end_of_pass_write_index, }); - let (pass, err) = gfx_select!(encoder => self.0.command_encoder_create_render_pass_dyn(*encoder, &wgc::command::RenderPassDescriptor { - label: desc.label.map(Borrowed), - timestamp_writes: timestamp_writes.as_ref(), - color_attachments: std::borrow::Cow::Borrowed(&colors), - depth_stencil_attachment: depth_stencil.as_ref(), - occlusion_query_set: desc.occlusion_query_set.map(|query_set| query_set.id.into()), - })); + let (pass, err) = self.0.command_encoder_create_render_pass_dyn( + *encoder, + &wgc::command::RenderPassDescriptor { + label: desc.label.map(Borrowed), + timestamp_writes: timestamp_writes.as_ref(), + color_attachments: std::borrow::Cow::Borrowed(&colors), + depth_stencil_attachment: depth_stencil.as_ref(), + occlusion_query_set: desc + .occlusion_query_set + .map(|query_set| query_set.id.into()), + }, + ); if let Some(cause) = err { self.handle_error( @@ -1976,8 +1966,7 @@ impl crate::Context for ContextWgpuCore { ) -> (Self::CommandBufferId, Self::CommandBufferData) { let descriptor = wgt::CommandBufferDescriptor::default(); encoder_data.open = false; // prevent the drop - let (id, error) = - wgc::gfx_select!(encoder => self.0.command_encoder_finish(encoder, &descriptor)); + let (id, error) = self.0.command_encoder_finish(encoder, &descriptor); if let Some(cause) = error { self.handle_error_nolabel(&encoder_data.error_sink, cause, "a CommandEncoder"); } @@ -1991,11 +1980,10 @@ impl crate::Context for ContextWgpuCore { texture: &crate::Texture, subresource_range: &wgt::ImageSubresourceRange, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_clear_texture( - *encoder, - texture.id.into(), - subresource_range - )) { + if let Err(cause) = + self.0 + .command_encoder_clear_texture(*encoder, texture.id.into(), subresource_range) + { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2012,11 +2000,10 @@ impl crate::Context for ContextWgpuCore { offset: wgt::BufferAddress, size: Option, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_clear_buffer( - *encoder, - buffer.id.into(), - offset, size - )) { + if let Err(cause) = + self.0 + .command_encoder_clear_buffer(*encoder, buffer.id.into(), offset, size) + { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2031,9 +2018,7 @@ impl crate::Context for ContextWgpuCore { encoder_data: &Self::CommandEncoderData, label: &str, ) { - if let Err(cause) = - wgc::gfx_select!(encoder => self.0.command_encoder_insert_debug_marker(*encoder, label)) - { + if let Err(cause) = self.0.command_encoder_insert_debug_marker(*encoder, label) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2048,9 +2033,7 @@ impl crate::Context for ContextWgpuCore { encoder_data: &Self::CommandEncoderData, label: &str, ) { - if let Err(cause) = - wgc::gfx_select!(encoder => self.0.command_encoder_push_debug_group(*encoder, label)) - { + if let Err(cause) = self.0.command_encoder_push_debug_group(*encoder, label) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2064,9 +2047,7 @@ impl crate::Context for ContextWgpuCore { encoder: &Self::CommandEncoderId, encoder_data: &Self::CommandEncoderData, ) { - if let Err(cause) = - wgc::gfx_select!(encoder => self.0.command_encoder_pop_debug_group(*encoder)) - { + if let Err(cause) = self.0.command_encoder_pop_debug_group(*encoder) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2083,11 +2064,10 @@ impl crate::Context for ContextWgpuCore { _query_set_data: &Self::QuerySetData, query_index: u32, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_write_timestamp( - *encoder, - *query_set, - query_index - )) { + if let Err(cause) = + self.0 + .command_encoder_write_timestamp(*encoder, *query_set, query_index) + { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2108,14 +2088,14 @@ impl crate::Context for ContextWgpuCore { _destination_data: &Self::BufferData, destination_offset: wgt::BufferAddress, ) { - if let Err(cause) = wgc::gfx_select!(encoder => self.0.command_encoder_resolve_query_set( + if let Err(cause) = self.0.command_encoder_resolve_query_set( *encoder, *query_set, first_query, query_count, *destination, - destination_offset - )) { + destination_offset, + ) { self.handle_error_nolabel( &encoder_data.error_sink, cause, @@ -2130,11 +2110,11 @@ impl crate::Context for ContextWgpuCore { encoder_data: Self::RenderBundleEncoderData, desc: &crate::RenderBundleDescriptor<'_>, ) -> (Self::RenderBundleId, Self::RenderBundleData) { - let (id, error) = wgc::gfx_select!(encoder_data.parent() => self.0.render_bundle_encoder_finish( + let (id, error) = self.0.render_bundle_encoder_finish( encoder_data, &desc.map_label(|l| l.map(Borrowed)), - None - )); + None, + ); if let Some(err) = error { self.handle_error_fatal(err, "RenderBundleEncoder::finish"); } @@ -2150,9 +2130,7 @@ impl crate::Context for ContextWgpuCore { offset: wgt::BufferAddress, data: &[u8], ) { - match wgc::gfx_select!( - *queue => self.0.queue_write_buffer(*queue, *buffer, offset, data) - ) { + match self.0.queue_write_buffer(*queue, *buffer, offset, data) { Ok(()) => (), Err(err) => { self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer") @@ -2169,9 +2147,10 @@ impl crate::Context for ContextWgpuCore { offset: wgt::BufferAddress, size: wgt::BufferSize, ) -> Option<()> { - match wgc::gfx_select!( - *queue => self.0.queue_validate_write_buffer(*queue, *buffer, offset, size) - ) { + match self + .0 + .queue_validate_write_buffer(*queue, *buffer, offset, size) + { Ok(()) => Some(()), Err(err) => { self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer_with"); @@ -2186,9 +2165,7 @@ impl crate::Context for ContextWgpuCore { queue_data: &Self::QueueData, size: wgt::BufferSize, ) -> Option> { - match wgc::gfx_select!( - *queue => self.0.queue_create_staging_buffer(*queue, size, None) - ) { + match self.0.queue_create_staging_buffer(*queue, size, None) { Ok((buffer_id, ptr)) => Some(Box::new(QueueWriteBuffer { buffer_id, mapping: BufferMappedRange { @@ -2216,9 +2193,10 @@ impl crate::Context for ContextWgpuCore { .as_any() .downcast_ref::() .unwrap(); - match wgc::gfx_select!( - *queue => self.0.queue_write_staging_buffer(*queue, *buffer, offset, staging_buffer.buffer_id) - ) { + match self + .0 + .queue_write_staging_buffer(*queue, *buffer, offset, staging_buffer.buffer_id) + { Ok(()) => (), Err(err) => { self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_buffer_with"); @@ -2235,13 +2213,13 @@ impl crate::Context for ContextWgpuCore { data_layout: wgt::ImageDataLayout, size: wgt::Extent3d, ) { - match wgc::gfx_select!(*queue => self.0.queue_write_texture( + match self.0.queue_write_texture( *queue, &map_texture_copy_view(texture), data, &data_layout, - &size - )) { + &size, + ) { Ok(()) => (), Err(err) => { self.handle_error_nolabel(&queue_data.error_sink, err, "Queue::write_texture") @@ -2258,12 +2236,12 @@ impl crate::Context for ContextWgpuCore { dest: crate::ImageCopyTextureTagged<'_>, size: wgt::Extent3d, ) { - match wgc::gfx_select!(*queue => self.0.queue_copy_external_image_to_texture( + match self.0.queue_copy_external_image_to_texture( *queue, source, map_texture_tagged_copy_view(dest), - size - )) { + size, + ) { Ok(()) => (), Err(err) => self.handle_error_nolabel( &queue_data.error_sink, @@ -2283,14 +2261,13 @@ impl crate::Context for ContextWgpuCore { .map(|(i, _)| i) .collect::>(); - let index = match wgc::gfx_select!(*queue => self.0.queue_submit(*queue, &temp_command_buffers)) - { + let index = match self.0.queue_submit(*queue, &temp_command_buffers) { Ok(index) => index, Err(err) => self.handle_error_fatal(err, "Queue::submit"), }; for cmdbuf in &temp_command_buffers { - wgc::gfx_select!(*queue => self.0.command_buffer_drop(*cmdbuf)); + self.0.command_buffer_drop(*cmdbuf); } index @@ -2301,9 +2278,7 @@ impl crate::Context for ContextWgpuCore { queue: &Self::QueueId, _queue_data: &Self::QueueData, ) -> f32 { - let res = wgc::gfx_select!(queue => self.0.queue_get_timestamp_period( - *queue - )); + let res = self.0.queue_get_timestamp_period(*queue); match res { Ok(v) => v, Err(cause) => { @@ -2320,18 +2295,18 @@ impl crate::Context for ContextWgpuCore { ) { let closure = wgc::device::queue::SubmittedWorkDoneClosure::from_rust(callback); - let res = wgc::gfx_select!(queue => self.0.queue_on_submitted_work_done(*queue, closure)); + let res = self.0.queue_on_submitted_work_done(*queue, closure); if let Err(cause) = res { self.handle_error_fatal(cause, "Queue::on_submitted_work_done"); } } fn device_start_capture(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { - wgc::gfx_select!(device => self.0.device_start_capture(*device)); + self.0.device_start_capture(*device); } fn device_stop_capture(&self, device: &Self::DeviceId, _device_data: &Self::DeviceData) { - wgc::gfx_select!(device => self.0.device_stop_capture(*device)); + self.0.device_stop_capture(*device); } fn device_get_internal_counters( @@ -2339,7 +2314,7 @@ impl crate::Context for ContextWgpuCore { device: &Self::DeviceId, _device_data: &Self::DeviceData, ) -> wgt::InternalCounters { - wgc::gfx_select!(device => self.0.device_get_internal_counters(*device)) + self.0.device_get_internal_counters(*device) } fn device_generate_allocator_report( @@ -2347,7 +2322,7 @@ impl crate::Context for ContextWgpuCore { device: &Self::DeviceId, _device_data: &Self::DeviceData, ) -> Option { - wgc::gfx_select!(device => self.0.device_generate_allocator_report(*device)) + self.0.device_generate_allocator_report(*device) } fn pipeline_cache_get_data( @@ -2356,7 +2331,7 @@ impl crate::Context for ContextWgpuCore { // TODO: Used for error handling? _cache_data: &Self::PipelineCacheData, ) -> Option> { - wgc::gfx_select!(cache => self.0.pipeline_cache_get_data(*cache)) + self.0.pipeline_cache_get_data(*cache) } fn compute_pass_set_pipeline( From 688c69393c3a7b5a0a009b5802e343283d2f69df Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 6 Aug 2024 23:29:21 +0200 Subject: [PATCH 51/53] remove dyn render & compute pass --- deno_webgpu/command_encoder.rs | 4 +- deno_webgpu/compute_pass.rs | 81 ++-- deno_webgpu/render_pass.rs | 219 ++++++----- wgpu-core/src/command/compute.rs | 15 +- wgpu-core/src/command/dyn_compute_pass.rs | 178 --------- wgpu-core/src/command/dyn_render_pass.rs | 458 ---------------------- wgpu-core/src/command/mod.rs | 7 +- wgpu-core/src/command/render.rs | 15 +- wgpu/src/backend/wgpu_core.rs | 233 ++++++----- 9 files changed, 312 insertions(+), 898 deletions(-) delete mode 100644 wgpu-core/src/command/dyn_compute_pass.rs delete mode 100644 wgpu-core/src/command/dyn_render_pass.rs diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 84537f3c0b..d7306a37a7 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -211,7 +211,7 @@ pub fn op_webgpu_command_encoder_begin_render_pass( }; let (render_pass, error) = - instance.command_encoder_create_render_pass_dyn(*command_encoder, &descriptor); + instance.command_encoder_create_render_pass(*command_encoder, &descriptor); let rid = state .resource_table .add(super::render_pass::WebGpuRenderPass(RefCell::new( @@ -264,7 +264,7 @@ pub fn op_webgpu_command_encoder_begin_compute_pass( }; let (compute_pass, error) = - instance.command_encoder_create_compute_pass_dyn(*command_encoder, &descriptor); + instance.command_encoder_create_compute_pass(*command_encoder, &descriptor); let rid = state .resource_table .add(super::compute_pass::WebGpuComputePass(RefCell::new( diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index 3b653ef349..e3e69860ab 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -10,9 +10,7 @@ use std::cell::RefCell; use super::error::WebGpuResult; -pub(crate) struct WebGpuComputePass( - pub(crate) RefCell>, -); +pub(crate) struct WebGpuComputePass(pub(crate) RefCell); impl Resource for WebGpuComputePass { fn name(&self) -> Cow { "webGPUComputePass".into() @@ -33,10 +31,12 @@ pub fn op_webgpu_compute_pass_set_pipeline( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource - .0 - .borrow_mut() - .set_pipeline(state.borrow(), compute_pipeline_resource.1)?; + state + .borrow::() + .compute_pass_set_pipeline( + &mut compute_pass_resource.0.borrow_mut(), + compute_pipeline_resource.1, + )?; Ok(WebGpuResult::empty()) } @@ -54,10 +54,9 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource - .0 - .borrow_mut() - .dispatch_workgroups(state.borrow(), x, y, z)?; + state + .borrow::() + .compute_pass_dispatch_workgroups(&mut compute_pass_resource.0.borrow_mut(), x, y, z)?; Ok(WebGpuResult::empty()) } @@ -77,10 +76,13 @@ pub fn op_webgpu_compute_pass_dispatch_workgroups_indirect( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource - .0 - .borrow_mut() - .dispatch_workgroups_indirect(state.borrow(), buffer_resource.1, indirect_offset)?; + state + .borrow::() + .compute_pass_dispatch_workgroups_indirect( + &mut compute_pass_resource.0.borrow_mut(), + buffer_resource.1, + indirect_offset, + )?; Ok(WebGpuResult::empty()) } @@ -95,7 +97,9 @@ pub fn op_webgpu_compute_pass_end( .resource_table .take::(compute_pass_rid)?; - compute_pass_resource.0.borrow_mut().end(state.borrow())?; + state + .borrow::() + .compute_pass_end(&mut compute_pass_resource.0.borrow_mut())?; Ok(WebGpuResult::empty()) } @@ -127,12 +131,14 @@ pub fn op_webgpu_compute_pass_set_bind_group( let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; - compute_pass_resource.0.borrow_mut().set_bind_group( - state.borrow(), - index, - bind_group_resource.1, - dynamic_offsets_data, - )?; + state + .borrow::() + .compute_pass_set_bind_group( + &mut compute_pass_resource.0.borrow_mut(), + index, + bind_group_resource.1, + dynamic_offsets_data, + )?; Ok(WebGpuResult::empty()) } @@ -148,11 +154,13 @@ pub fn op_webgpu_compute_pass_push_debug_group( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource.0.borrow_mut().push_debug_group( - state.borrow(), - group_label, - 0, // wgpu#975 - )?; + state + .borrow::() + .compute_pass_push_debug_group( + &mut compute_pass_resource.0.borrow_mut(), + group_label, + 0, // wgpu#975 + )?; Ok(WebGpuResult::empty()) } @@ -167,10 +175,9 @@ pub fn op_webgpu_compute_pass_pop_debug_group( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource - .0 - .borrow_mut() - .pop_debug_group(state.borrow())?; + state + .borrow::() + .compute_pass_pop_debug_group(&mut compute_pass_resource.0.borrow_mut())?; Ok(WebGpuResult::empty()) } @@ -186,11 +193,13 @@ pub fn op_webgpu_compute_pass_insert_debug_marker( .resource_table .get::(compute_pass_rid)?; - compute_pass_resource.0.borrow_mut().insert_debug_marker( - state.borrow(), - marker_label, - 0, // wgpu#975 - )?; + state + .borrow::() + .compute_pass_insert_debug_marker( + &mut compute_pass_resource.0.borrow_mut(), + marker_label, + 0, // wgpu#975 + )?; Ok(WebGpuResult::empty()) } diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index 941245971c..2d4557cf03 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -12,7 +12,7 @@ use std::cell::RefCell; use super::error::WebGpuResult; -pub(crate) struct WebGpuRenderPass(pub(crate) RefCell>); +pub(crate) struct WebGpuRenderPass(pub(crate) RefCell); impl Resource for WebGpuRenderPass { fn name(&self) -> Cow { "webGPURenderPass".into() @@ -41,15 +41,17 @@ pub fn op_webgpu_render_pass_set_viewport( .resource_table .get::(args.render_pass_rid)?; - render_pass_resource.0.borrow_mut().set_viewport( - state.borrow(), - args.x, - args.y, - args.width, - args.height, - args.min_depth, - args.max_depth, - )?; + state + .borrow::() + .render_pass_set_viewport( + &mut render_pass_resource.0.borrow_mut(), + args.x, + args.y, + args.width, + args.height, + args.min_depth, + args.max_depth, + )?; Ok(WebGpuResult::empty()) } @@ -68,10 +70,15 @@ pub fn op_webgpu_render_pass_set_scissor_rect( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .set_scissor_rect(state.borrow(), x, y, width, height)?; + state + .borrow::() + .render_pass_set_scissor_rect( + &mut render_pass_resource.0.borrow_mut(), + x, + y, + width, + height, + )?; Ok(WebGpuResult::empty()) } @@ -87,10 +94,9 @@ pub fn op_webgpu_render_pass_set_blend_constant( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .set_blend_constant(state.borrow(), color)?; + state + .borrow::() + .render_pass_set_blend_constant(&mut render_pass_resource.0.borrow_mut(), color)?; Ok(WebGpuResult::empty()) } @@ -106,10 +112,9 @@ pub fn op_webgpu_render_pass_set_stencil_reference( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .set_stencil_reference(state.borrow(), reference)?; + state + .borrow::() + .render_pass_set_stencil_reference(&mut render_pass_resource.0.borrow_mut(), reference)?; Ok(WebGpuResult::empty()) } @@ -125,10 +130,9 @@ pub fn op_webgpu_render_pass_begin_occlusion_query( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .begin_occlusion_query(state.borrow(), query_index)?; + state + .borrow::() + .render_pass_begin_occlusion_query(&mut render_pass_resource.0.borrow_mut(), query_index)?; Ok(WebGpuResult::empty()) } @@ -143,10 +147,9 @@ pub fn op_webgpu_render_pass_end_occlusion_query( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .end_occlusion_query(state.borrow())?; + state + .borrow::() + .render_pass_end_occlusion_query(&mut render_pass_resource.0.borrow_mut())?; Ok(WebGpuResult::empty()) } @@ -172,10 +175,9 @@ pub fn op_webgpu_render_pass_execute_bundles( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .execute_bundles(state.borrow(), &bundles)?; + state + .borrow::() + .render_pass_execute_bundles(&mut render_pass_resource.0.borrow_mut(), &bundles)?; Ok(WebGpuResult::empty()) } @@ -190,7 +192,9 @@ pub fn op_webgpu_render_pass_end( .resource_table .take::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().end(state.borrow())?; + state + .borrow::() + .render_pass_end(&mut render_pass_resource.0.borrow_mut())?; Ok(WebGpuResult::empty()) } @@ -222,12 +226,14 @@ pub fn op_webgpu_render_pass_set_bind_group( let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len]; - render_pass_resource.0.borrow_mut().set_bind_group( - state.borrow(), - index, - bind_group_resource.1, - dynamic_offsets_data, - )?; + state + .borrow::() + .render_pass_set_bind_group( + &mut render_pass_resource.0.borrow_mut(), + index, + bind_group_resource.1, + dynamic_offsets_data, + )?; Ok(WebGpuResult::empty()) } @@ -243,11 +249,13 @@ pub fn op_webgpu_render_pass_push_debug_group( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().push_debug_group( - state.borrow(), - group_label, - 0, // wgpu#975 - )?; + state + .borrow::() + .render_pass_push_debug_group( + &mut render_pass_resource.0.borrow_mut(), + group_label, + 0, // wgpu#975 + )?; Ok(WebGpuResult::empty()) } @@ -262,10 +270,9 @@ pub fn op_webgpu_render_pass_pop_debug_group( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .pop_debug_group(state.borrow())?; + state + .borrow::() + .render_pass_pop_debug_group(&mut render_pass_resource.0.borrow_mut())?; Ok(WebGpuResult::empty()) } @@ -281,11 +288,13 @@ pub fn op_webgpu_render_pass_insert_debug_marker( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().insert_debug_marker( - state.borrow(), - marker_label, - 0, // wgpu#975 - )?; + state + .borrow::() + .render_pass_insert_debug_marker( + &mut render_pass_resource.0.borrow_mut(), + marker_label, + 0, // wgpu#975 + )?; Ok(WebGpuResult::empty()) } @@ -304,10 +313,12 @@ pub fn op_webgpu_render_pass_set_pipeline( .resource_table .get::(render_pass_rid)?; - render_pass_resource - .0 - .borrow_mut() - .set_pipeline(state.borrow(), render_pipeline_resource.1)?; + state + .borrow::() + .render_pass_set_pipeline( + &mut render_pass_resource.0.borrow_mut(), + render_pipeline_resource.1, + )?; Ok(WebGpuResult::empty()) } @@ -338,13 +349,15 @@ pub fn op_webgpu_render_pass_set_index_buffer( None }; - render_pass_resource.0.borrow_mut().set_index_buffer( - state.borrow(), - buffer_resource.1, - index_format, - offset, - size, - )?; + state + .borrow::() + .render_pass_set_index_buffer( + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.1, + index_format, + offset, + size, + )?; Ok(WebGpuResult::empty()) } @@ -375,13 +388,15 @@ pub fn op_webgpu_render_pass_set_vertex_buffer( None }; - render_pass_resource.0.borrow_mut().set_vertex_buffer( - state.borrow(), - slot, - buffer_resource.1, - offset, - size, - )?; + state + .borrow::() + .render_pass_set_vertex_buffer( + &mut render_pass_resource.0.borrow_mut(), + slot, + buffer_resource.1, + offset, + size, + )?; Ok(WebGpuResult::empty()) } @@ -400,13 +415,15 @@ pub fn op_webgpu_render_pass_draw( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().draw( - state.borrow(), - vertex_count, - instance_count, - first_vertex, - first_instance, - )?; + state + .borrow::() + .render_pass_draw( + &mut render_pass_resource.0.borrow_mut(), + vertex_count, + instance_count, + first_vertex, + first_instance, + )?; Ok(WebGpuResult::empty()) } @@ -426,14 +443,16 @@ pub fn op_webgpu_render_pass_draw_indexed( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().draw_indexed( - state.borrow(), - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - )?; + state + .borrow::() + .render_pass_draw_indexed( + &mut render_pass_resource.0.borrow_mut(), + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + )?; Ok(WebGpuResult::empty()) } @@ -453,11 +472,13 @@ pub fn op_webgpu_render_pass_draw_indirect( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().draw_indirect( - state.borrow(), - buffer_resource.1, - indirect_offset, - )?; + state + .borrow::() + .render_pass_draw_indirect( + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.1, + indirect_offset, + )?; Ok(WebGpuResult::empty()) } @@ -477,11 +498,13 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect( .resource_table .get::(render_pass_rid)?; - render_pass_resource.0.borrow_mut().draw_indexed_indirect( - state.borrow(), - buffer_resource.1, - indirect_offset, - )?; + state + .borrow::() + .render_pass_draw_indexed_indirect( + &mut render_pass_resource.0.borrow_mut(), + buffer_resource.1, + indirect_offset, + )?; Ok(WebGpuResult::empty()) } diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 93e7c15168..5f23fb7221 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -31,7 +31,7 @@ use wgt::{BufferAddress, DynamicOffset}; use std::sync::Arc; use std::{fmt, mem, str}; -use super::{bind::BinderError, memory_init::CommandBufferTextureMemoryActions, DynComputePass}; +use super::{bind::BinderError, memory_init::CommandBufferTextureMemoryActions}; pub struct ComputePass { /// All pass data & records is stored here. @@ -328,19 +328,6 @@ impl Global { (ComputePass::new(Some(cmd_buf), arc_desc), None) } - /// Creates a type erased compute pass. - /// - /// If creation fails, an invalid pass is returned. - /// Any operation on an invalid pass will return an error. - pub fn command_encoder_create_compute_pass_dyn( - &self, - encoder_id: id::CommandEncoderId, - desc: &ComputePassDescriptor, - ) -> (Box, Option) { - let (pass, err) = self.command_encoder_create_compute_pass(encoder_id, desc); - (Box::new(pass), err) - } - pub fn compute_pass_end(&self, pass: &mut ComputePass) -> Result<(), ComputePassError> { let scope = PassErrorScope::Pass; diff --git a/wgpu-core/src/command/dyn_compute_pass.rs b/wgpu-core/src/command/dyn_compute_pass.rs deleted file mode 100644 index 273feaddf7..0000000000 --- a/wgpu-core/src/command/dyn_compute_pass.rs +++ /dev/null @@ -1,178 +0,0 @@ -use wgt::WasmNotSendSync; - -use crate::{global, id}; - -use super::{ComputePass, ComputePassError}; - -/// Trait for type erasing ComputePass. -// TODO(#5124): wgpu-core's ComputePass trait should not be hal type dependent. -// Practically speaking this allows us merge gfx_select with type erasure: -// The alternative would be to introduce ComputePassId which then first needs to be looked up and then dispatch via gfx_select. -pub trait DynComputePass: std::fmt::Debug + WasmNotSendSync { - fn set_bind_group( - &mut self, - context: &global::Global, - index: u32, - bind_group_id: id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) -> Result<(), ComputePassError>; - fn set_pipeline( - &mut self, - context: &global::Global, - pipeline_id: id::ComputePipelineId, - ) -> Result<(), ComputePassError>; - fn set_push_constants( - &mut self, - context: &global::Global, - offset: u32, - data: &[u8], - ) -> Result<(), ComputePassError>; - fn dispatch_workgroups( - &mut self, - context: &global::Global, - groups_x: u32, - groups_y: u32, - groups_z: u32, - ) -> Result<(), ComputePassError>; - fn dispatch_workgroups_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), ComputePassError>; - fn push_debug_group( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), ComputePassError>; - fn pop_debug_group(&mut self, context: &global::Global) -> Result<(), ComputePassError>; - fn insert_debug_marker( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), ComputePassError>; - fn write_timestamp( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), ComputePassError>; - fn begin_pipeline_statistics_query( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), ComputePassError>; - fn end_pipeline_statistics_query( - &mut self, - context: &global::Global, - ) -> Result<(), ComputePassError>; - fn end(&mut self, context: &global::Global) -> Result<(), ComputePassError>; - - fn label(&self) -> Option<&str>; -} - -impl DynComputePass for ComputePass { - fn set_bind_group( - &mut self, - context: &global::Global, - index: u32, - bind_group_id: id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) -> Result<(), ComputePassError> { - context.compute_pass_set_bind_group(self, index, bind_group_id, offsets) - } - - fn set_pipeline( - &mut self, - context: &global::Global, - pipeline_id: id::ComputePipelineId, - ) -> Result<(), ComputePassError> { - context.compute_pass_set_pipeline(self, pipeline_id) - } - - fn set_push_constants( - &mut self, - context: &global::Global, - offset: u32, - data: &[u8], - ) -> Result<(), ComputePassError> { - context.compute_pass_set_push_constants(self, offset, data) - } - - fn dispatch_workgroups( - &mut self, - context: &global::Global, - groups_x: u32, - groups_y: u32, - groups_z: u32, - ) -> Result<(), ComputePassError> { - context.compute_pass_dispatch_workgroups(self, groups_x, groups_y, groups_z) - } - - fn dispatch_workgroups_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), ComputePassError> { - context.compute_pass_dispatch_workgroups_indirect(self, buffer_id, offset) - } - - fn push_debug_group( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), ComputePassError> { - context.compute_pass_push_debug_group(self, label, color) - } - - fn pop_debug_group(&mut self, context: &global::Global) -> Result<(), ComputePassError> { - context.compute_pass_pop_debug_group(self) - } - - fn insert_debug_marker( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), ComputePassError> { - context.compute_pass_insert_debug_marker(self, label, color) - } - - fn write_timestamp( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), ComputePassError> { - context.compute_pass_write_timestamp(self, query_set_id, query_index) - } - - fn begin_pipeline_statistics_query( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), ComputePassError> { - context.compute_pass_begin_pipeline_statistics_query(self, query_set_id, query_index) - } - - fn end_pipeline_statistics_query( - &mut self, - context: &global::Global, - ) -> Result<(), ComputePassError> { - context.compute_pass_end_pipeline_statistics_query(self) - } - - fn end(&mut self, context: &global::Global) -> Result<(), ComputePassError> { - context.compute_pass_end(self) - } - - fn label(&self) -> Option<&str> { - self.label() - } -} diff --git a/wgpu-core/src/command/dyn_render_pass.rs b/wgpu-core/src/command/dyn_render_pass.rs deleted file mode 100644 index d20ca09780..0000000000 --- a/wgpu-core/src/command/dyn_render_pass.rs +++ /dev/null @@ -1,458 +0,0 @@ -use wgt::WasmNotSendSync; - -use crate::{global, id}; - -use super::{RenderPass, RenderPassError}; - -/// Trait for type erasing RenderPass. -// TODO(#5124): wgpu-core's RenderPass trait should not be hal type dependent. -// Practically speaking this allows us merge gfx_select with type erasure: -// The alternative would be to introduce RenderPassId which then first needs to be looked up and then dispatch via gfx_select. -pub trait DynRenderPass: std::fmt::Debug + WasmNotSendSync { - fn set_bind_group( - &mut self, - context: &global::Global, - index: u32, - bind_group_id: id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) -> Result<(), RenderPassError>; - fn set_index_buffer( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - index_format: wgt::IndexFormat, - offset: wgt::BufferAddress, - size: Option, - ) -> Result<(), RenderPassError>; - fn set_vertex_buffer( - &mut self, - context: &global::Global, - slot: u32, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - size: Option, - ) -> Result<(), RenderPassError>; - fn set_pipeline( - &mut self, - context: &global::Global, - pipeline_id: id::RenderPipelineId, - ) -> Result<(), RenderPassError>; - fn set_push_constants( - &mut self, - context: &global::Global, - stages: wgt::ShaderStages, - offset: u32, - data: &[u8], - ) -> Result<(), RenderPassError>; - fn draw( - &mut self, - context: &global::Global, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, - ) -> Result<(), RenderPassError>; - fn draw_indexed( - &mut self, - context: &global::Global, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, - ) -> Result<(), RenderPassError>; - fn draw_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), RenderPassError>; - fn draw_indexed_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), RenderPassError>; - fn multi_draw_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count: u32, - ) -> Result<(), RenderPassError>; - fn multi_draw_indexed_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count: u32, - ) -> Result<(), RenderPassError>; - fn multi_draw_indirect_count( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count_buffer_id: id::BufferId, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) -> Result<(), RenderPassError>; - fn multi_draw_indexed_indirect_count( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count_buffer_id: id::BufferId, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) -> Result<(), RenderPassError>; - fn set_blend_constant( - &mut self, - context: &global::Global, - color: wgt::Color, - ) -> Result<(), RenderPassError>; - fn set_scissor_rect( - &mut self, - context: &global::Global, - x: u32, - y: u32, - width: u32, - height: u32, - ) -> Result<(), RenderPassError>; - fn set_viewport( - &mut self, - context: &global::Global, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, - ) -> Result<(), RenderPassError>; - fn set_stencil_reference( - &mut self, - context: &global::Global, - reference: u32, - ) -> Result<(), RenderPassError>; - fn push_debug_group( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), RenderPassError>; - fn pop_debug_group(&mut self, context: &global::Global) -> Result<(), RenderPassError>; - fn insert_debug_marker( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), RenderPassError>; - fn write_timestamp( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), RenderPassError>; - fn begin_occlusion_query( - &mut self, - context: &global::Global, - query_index: u32, - ) -> Result<(), RenderPassError>; - fn end_occlusion_query(&mut self, context: &global::Global) -> Result<(), RenderPassError>; - fn begin_pipeline_statistics_query( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), RenderPassError>; - fn end_pipeline_statistics_query( - &mut self, - context: &global::Global, - ) -> Result<(), RenderPassError>; - fn execute_bundles( - &mut self, - context: &global::Global, - bundles: &[id::RenderBundleId], - ) -> Result<(), RenderPassError>; - fn end(&mut self, context: &global::Global) -> Result<(), RenderPassError>; - - fn label(&self) -> Option<&str>; -} - -impl DynRenderPass for RenderPass { - fn set_index_buffer( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - index_format: wgt::IndexFormat, - offset: wgt::BufferAddress, - size: Option, - ) -> Result<(), RenderPassError> { - context.render_pass_set_index_buffer(self, buffer_id, index_format, offset, size) - } - - fn set_vertex_buffer( - &mut self, - context: &global::Global, - slot: u32, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - size: Option, - ) -> Result<(), RenderPassError> { - context.render_pass_set_vertex_buffer(self, slot, buffer_id, offset, size) - } - - fn set_bind_group( - &mut self, - context: &global::Global, - index: u32, - bind_group_id: id::BindGroupId, - offsets: &[wgt::DynamicOffset], - ) -> Result<(), RenderPassError> { - context.render_pass_set_bind_group(self, index, bind_group_id, offsets) - } - - fn set_pipeline( - &mut self, - context: &global::Global, - pipeline_id: id::RenderPipelineId, - ) -> Result<(), RenderPassError> { - context.render_pass_set_pipeline(self, pipeline_id) - } - - fn set_push_constants( - &mut self, - context: &global::Global, - stages: wgt::ShaderStages, - offset: u32, - data: &[u8], - ) -> Result<(), RenderPassError> { - context.render_pass_set_push_constants(self, stages, offset, data) - } - - fn draw( - &mut self, - context: &global::Global, - vertex_count: u32, - instance_count: u32, - first_vertex: u32, - first_instance: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_draw( - self, - vertex_count, - instance_count, - first_vertex, - first_instance, - ) - } - - fn draw_indexed( - &mut self, - context: &global::Global, - index_count: u32, - instance_count: u32, - first_index: u32, - base_vertex: i32, - first_instance: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_draw_indexed( - self, - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ) - } - - fn draw_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), RenderPassError> { - context.render_pass_draw_indirect(self, buffer_id, offset) - } - - fn draw_indexed_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - ) -> Result<(), RenderPassError> { - context.render_pass_draw_indexed_indirect(self, buffer_id, offset) - } - - fn multi_draw_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_multi_draw_indirect(self, buffer_id, offset, count) - } - - fn multi_draw_indexed_indirect( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_multi_draw_indexed_indirect(self, buffer_id, offset, count) - } - - fn multi_draw_indirect_count( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count_buffer_id: id::BufferId, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_multi_draw_indirect_count( - self, - buffer_id, - offset, - count_buffer_id, - count_buffer_offset, - max_count, - ) - } - - fn multi_draw_indexed_indirect_count( - &mut self, - context: &global::Global, - buffer_id: id::BufferId, - offset: wgt::BufferAddress, - count_buffer_id: id::BufferId, - count_buffer_offset: wgt::BufferAddress, - max_count: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_multi_draw_indexed_indirect_count( - self, - buffer_id, - offset, - count_buffer_id, - count_buffer_offset, - max_count, - ) - } - - fn set_blend_constant( - &mut self, - context: &global::Global, - color: wgt::Color, - ) -> Result<(), RenderPassError> { - context.render_pass_set_blend_constant(self, color) - } - - fn set_scissor_rect( - &mut self, - context: &global::Global, - x: u32, - y: u32, - width: u32, - height: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_set_scissor_rect(self, x, y, width, height) - } - - fn set_viewport( - &mut self, - context: &global::Global, - x: f32, - y: f32, - width: f32, - height: f32, - min_depth: f32, - max_depth: f32, - ) -> Result<(), RenderPassError> { - context.render_pass_set_viewport(self, x, y, width, height, min_depth, max_depth) - } - - fn set_stencil_reference( - &mut self, - context: &global::Global, - reference: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_set_stencil_reference(self, reference) - } - - fn push_debug_group( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_push_debug_group(self, label, color) - } - - fn pop_debug_group(&mut self, context: &global::Global) -> Result<(), RenderPassError> { - context.render_pass_pop_debug_group(self) - } - - fn insert_debug_marker( - &mut self, - context: &global::Global, - label: &str, - color: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_insert_debug_marker(self, label, color) - } - - fn write_timestamp( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_write_timestamp(self, query_set_id, query_index) - } - - fn begin_occlusion_query( - &mut self, - context: &global::Global, - query_index: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_begin_occlusion_query(self, query_index) - } - - fn end_occlusion_query(&mut self, context: &global::Global) -> Result<(), RenderPassError> { - context.render_pass_end_occlusion_query(self) - } - - fn begin_pipeline_statistics_query( - &mut self, - context: &global::Global, - query_set_id: id::QuerySetId, - query_index: u32, - ) -> Result<(), RenderPassError> { - context.render_pass_begin_pipeline_statistics_query(self, query_set_id, query_index) - } - - fn end_pipeline_statistics_query( - &mut self, - context: &global::Global, - ) -> Result<(), RenderPassError> { - context.render_pass_end_pipeline_statistics_query(self) - } - - fn execute_bundles( - &mut self, - context: &global::Global, - bundles: &[id::RenderBundleId], - ) -> Result<(), RenderPassError> { - context.render_pass_execute_bundles(self, bundles) - } - - fn end(&mut self, context: &global::Global) -> Result<(), RenderPassError> { - context.render_pass_end(self) - } - - fn label(&self) -> Option<&str> { - self.label() - } -} diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index d2714087df..313bf813a1 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -5,8 +5,6 @@ mod clear; mod compute; mod compute_command; mod draw; -mod dyn_compute_pass; -mod dyn_render_pass; mod memory_init; mod query; mod render; @@ -18,9 +16,8 @@ use std::sync::Arc; pub(crate) use self::clear::clear_texture; pub use self::{ - bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, - dyn_compute_pass::DynComputePass, dyn_render_pass::DynRenderPass, query::*, render::*, - render_command::RenderCommand, transfer::*, + bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, query::*, + render::*, render_command::RenderCommand, transfer::*, }; pub(crate) use allocator::CommandAllocator; diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 1128e60a54..1f11ba0937 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -52,7 +52,7 @@ use super::{ memory_init::TextureSurfaceDiscard, CommandBufferTextureMemoryActions, CommandEncoder, QueryResetMap, }; -use super::{DrawKind, DynRenderPass, Rect}; +use super::{DrawKind, Rect}; /// Operation to perform to the output attachment at the start of a renderpass. #[repr(C)] @@ -1461,19 +1461,6 @@ impl Global { (RenderPass::new(Some(cmd_buf), arc_desc), err) } - /// Creates a type erased render pass. - /// - /// If creation fails, an invalid pass is returned. - /// Any operation on an invalid pass will return an error. - pub fn command_encoder_create_render_pass_dyn( - &self, - encoder_id: id::CommandEncoderId, - desc: &RenderPassDescriptor<'_>, - ) -> (Box, Option) { - let (pass, err) = self.command_encoder_create_render_pass(encoder_id, desc); - (Box::new(pass), err) - } - #[doc(hidden)] #[cfg(any(feature = "serde", feature = "replay"))] pub fn render_pass_end_with_unresolved_commands( diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 30a8743fb2..413524ab0d 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -489,13 +489,13 @@ impl Queue { #[derive(Debug)] pub struct ComputePass { - pass: Box, + pass: wgc::command::ComputePass, error_sink: ErrorSink, } #[derive(Debug)] pub struct RenderPass { - pass: Box, + pass: wgc::command::RenderPass, error_sink: ErrorSink, } @@ -1866,7 +1866,7 @@ impl crate::Context for ContextWgpuCore { end_of_pass_write_index: tw.end_of_pass_write_index, }); - let (pass, err) = self.0.command_encoder_create_compute_pass_dyn( + let (pass, err) = self.0.command_encoder_create_compute_pass( *encoder, &wgc::command::ComputePassDescriptor { label: desc.label.map(Borrowed), @@ -1928,7 +1928,7 @@ impl crate::Context for ContextWgpuCore { end_of_pass_write_index: tw.end_of_pass_write_index, }); - let (pass, err) = self.0.command_encoder_create_render_pass_dyn( + let (pass, err) = self.0.command_encoder_create_render_pass( *encoder, &wgc::command::RenderPassDescriptor { label: desc.label.map(Borrowed), @@ -2341,7 +2341,10 @@ impl crate::Context for ContextWgpuCore { pipeline: &Self::ComputePipelineId, _pipeline_data: &Self::ComputePipelineData, ) { - if let Err(cause) = pass_data.pass.set_pipeline(&self.0, *pipeline) { + if let Err(cause) = self + .0 + .compute_pass_set_pipeline(&mut pass_data.pass, *pipeline) + { self.handle_error( &pass_data.error_sink, cause, @@ -2360,9 +2363,9 @@ impl crate::Context for ContextWgpuCore { _bind_group_data: &Self::BindGroupData, offsets: &[wgt::DynamicOffset], ) { - if let Err(cause) = pass_data - .pass - .set_bind_group(&self.0, index, *bind_group, offsets) + if let Err(cause) = + self.0 + .compute_pass_set_bind_group(&mut pass_data.pass, index, *bind_group, offsets) { self.handle_error( &pass_data.error_sink, @@ -2380,7 +2383,10 @@ impl crate::Context for ContextWgpuCore { offset: u32, data: &[u8], ) { - if let Err(cause) = pass_data.pass.set_push_constants(&self.0, offset, data) { + if let Err(cause) = + self.0 + .compute_pass_set_push_constants(&mut pass_data.pass, offset, data) + { self.handle_error( &pass_data.error_sink, cause, @@ -2396,7 +2402,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::ComputePassData, label: &str, ) { - if let Err(cause) = pass_data.pass.insert_debug_marker(&self.0, label, 0) { + if let Err(cause) = self + .0 + .compute_pass_insert_debug_marker(&mut pass_data.pass, label, 0) + { self.handle_error( &pass_data.error_sink, cause, @@ -2412,7 +2421,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::ComputePassData, group_label: &str, ) { - if let Err(cause) = pass_data.pass.push_debug_group(&self.0, group_label, 0) { + if let Err(cause) = + self.0 + .compute_pass_push_debug_group(&mut pass_data.pass, group_label, 0) + { self.handle_error( &pass_data.error_sink, cause, @@ -2427,7 +2439,7 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::ComputePassId, pass_data: &mut Self::ComputePassData, ) { - if let Err(cause) = pass_data.pass.pop_debug_group(&self.0) { + if let Err(cause) = self.0.compute_pass_pop_debug_group(&mut pass_data.pass) { self.handle_error( &pass_data.error_sink, cause, @@ -2445,9 +2457,9 @@ impl crate::Context for ContextWgpuCore { _query_set_data: &Self::QuerySetData, query_index: u32, ) { - if let Err(cause) = pass_data - .pass - .write_timestamp(&self.0, *query_set, query_index) + if let Err(cause) = + self.0 + .compute_pass_write_timestamp(&mut pass_data.pass, *query_set, query_index) { self.handle_error( &pass_data.error_sink, @@ -2466,11 +2478,11 @@ impl crate::Context for ContextWgpuCore { _query_set_data: &Self::QuerySetData, query_index: u32, ) { - if let Err(cause) = - pass_data - .pass - .begin_pipeline_statistics_query(&self.0, *query_set, query_index) - { + if let Err(cause) = self.0.compute_pass_begin_pipeline_statistics_query( + &mut pass_data.pass, + *query_set, + query_index, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -2485,7 +2497,10 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::ComputePassId, pass_data: &mut Self::ComputePassData, ) { - if let Err(cause) = pass_data.pass.end_pipeline_statistics_query(&self.0) { + if let Err(cause) = self + .0 + .compute_pass_end_pipeline_statistics_query(&mut pass_data.pass) + { self.handle_error( &pass_data.error_sink, cause, @@ -2503,7 +2518,10 @@ impl crate::Context for ContextWgpuCore { y: u32, z: u32, ) { - if let Err(cause) = pass_data.pass.dispatch_workgroups(&self.0, x, y, z) { + if let Err(cause) = self + .0 + .compute_pass_dispatch_workgroups(&mut pass_data.pass, x, y, z) + { self.handle_error( &pass_data.error_sink, cause, @@ -2521,11 +2539,11 @@ impl crate::Context for ContextWgpuCore { _indirect_buffer_data: &Self::BufferData, indirect_offset: wgt::BufferAddress, ) { - if let Err(cause) = - pass_data - .pass - .dispatch_workgroups_indirect(&self.0, *indirect_buffer, indirect_offset) - { + if let Err(cause) = self.0.compute_pass_dispatch_workgroups_indirect( + &mut pass_data.pass, + *indirect_buffer, + indirect_offset, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -2540,7 +2558,7 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::ComputePassId, pass_data: &mut Self::ComputePassData, ) { - if let Err(cause) = pass_data.pass.end(&self.0) { + if let Err(cause) = self.0.compute_pass_end(&mut pass_data.pass) { self.handle_error( &pass_data.error_sink, cause, @@ -2742,7 +2760,10 @@ impl crate::Context for ContextWgpuCore { pipeline: &Self::RenderPipelineId, _pipeline_data: &Self::RenderPipelineData, ) { - if let Err(cause) = pass_data.pass.set_pipeline(&self.0, *pipeline) { + if let Err(cause) = self + .0 + .render_pass_set_pipeline(&mut pass_data.pass, *pipeline) + { self.handle_error( &pass_data.error_sink, cause, @@ -2761,9 +2782,9 @@ impl crate::Context for ContextWgpuCore { _bind_group_data: &Self::BindGroupData, offsets: &[wgt::DynamicOffset], ) { - if let Err(cause) = pass_data - .pass - .set_bind_group(&self.0, index, *bind_group, offsets) + if let Err(cause) = + self.0 + .render_pass_set_bind_group(&mut pass_data.pass, index, *bind_group, offsets) { self.handle_error( &pass_data.error_sink, @@ -2784,11 +2805,13 @@ impl crate::Context for ContextWgpuCore { offset: wgt::BufferAddress, size: Option, ) { - if let Err(cause) = - pass_data - .pass - .set_index_buffer(&self.0, *buffer, index_format, offset, size) - { + if let Err(cause) = self.0.render_pass_set_index_buffer( + &mut pass_data.pass, + *buffer, + index_format, + offset, + size, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -2808,9 +2831,9 @@ impl crate::Context for ContextWgpuCore { offset: wgt::BufferAddress, size: Option, ) { - if let Err(cause) = pass_data - .pass - .set_vertex_buffer(&self.0, slot, *buffer, offset, size) + if let Err(cause) = + self.0 + .render_pass_set_vertex_buffer(&mut pass_data.pass, slot, *buffer, offset, size) { self.handle_error( &pass_data.error_sink, @@ -2829,9 +2852,9 @@ impl crate::Context for ContextWgpuCore { offset: u32, data: &[u8], ) { - if let Err(cause) = pass_data - .pass - .set_push_constants(&self.0, stages, offset, data) + if let Err(cause) = + self.0 + .render_pass_set_push_constants(&mut pass_data.pass, stages, offset, data) { self.handle_error( &pass_data.error_sink, @@ -2849,8 +2872,8 @@ impl crate::Context for ContextWgpuCore { vertices: Range, instances: Range, ) { - if let Err(cause) = pass_data.pass.draw( - &self.0, + if let Err(cause) = self.0.render_pass_draw( + &mut pass_data.pass, vertices.end - vertices.start, instances.end - instances.start, vertices.start, @@ -2873,8 +2896,8 @@ impl crate::Context for ContextWgpuCore { base_vertex: i32, instances: Range, ) { - if let Err(cause) = pass_data.pass.draw_indexed( - &self.0, + if let Err(cause) = self.0.render_pass_draw_indexed( + &mut pass_data.pass, indices.end - indices.start, instances.end - instances.start, indices.start, @@ -2898,9 +2921,9 @@ impl crate::Context for ContextWgpuCore { _indirect_buffer_data: &Self::BufferData, indirect_offset: wgt::BufferAddress, ) { - if let Err(cause) = pass_data - .pass - .draw_indirect(&self.0, *indirect_buffer, indirect_offset) + if let Err(cause) = + self.0 + .render_pass_draw_indirect(&mut pass_data.pass, *indirect_buffer, indirect_offset) { self.handle_error( &pass_data.error_sink, @@ -2919,11 +2942,11 @@ impl crate::Context for ContextWgpuCore { _indirect_buffer_data: &Self::BufferData, indirect_offset: wgt::BufferAddress, ) { - if let Err(cause) = - pass_data - .pass - .draw_indexed_indirect(&self.0, *indirect_buffer, indirect_offset) - { + if let Err(cause) = self.0.render_pass_draw_indexed_indirect( + &mut pass_data.pass, + *indirect_buffer, + indirect_offset, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -2942,11 +2965,12 @@ impl crate::Context for ContextWgpuCore { indirect_offset: wgt::BufferAddress, count: u32, ) { - if let Err(cause) = - pass_data - .pass - .multi_draw_indirect(&self.0, *indirect_buffer, indirect_offset, count) - { + if let Err(cause) = self.0.render_pass_multi_draw_indirect( + &mut pass_data.pass, + *indirect_buffer, + indirect_offset, + count, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -2965,8 +2989,8 @@ impl crate::Context for ContextWgpuCore { indirect_offset: wgt::BufferAddress, count: u32, ) { - if let Err(cause) = pass_data.pass.multi_draw_indexed_indirect( - &self.0, + if let Err(cause) = self.0.render_pass_multi_draw_indexed_indirect( + &mut pass_data.pass, *indirect_buffer, indirect_offset, count, @@ -2992,8 +3016,8 @@ impl crate::Context for ContextWgpuCore { count_buffer_offset: wgt::BufferAddress, max_count: u32, ) { - if let Err(cause) = pass_data.pass.multi_draw_indirect_count( - &self.0, + if let Err(cause) = self.0.render_pass_multi_draw_indirect_count( + &mut pass_data.pass, *indirect_buffer, indirect_offset, *count_buffer, @@ -3021,8 +3045,8 @@ impl crate::Context for ContextWgpuCore { count_buffer_offset: wgt::BufferAddress, max_count: u32, ) { - if let Err(cause) = pass_data.pass.multi_draw_indexed_indirect_count( - &self.0, + if let Err(cause) = self.0.render_pass_multi_draw_indexed_indirect_count( + &mut pass_data.pass, *indirect_buffer, indirect_offset, *count_buffer, @@ -3044,7 +3068,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::RenderPassData, color: wgt::Color, ) { - if let Err(cause) = pass_data.pass.set_blend_constant(&self.0, color) { + if let Err(cause) = self + .0 + .render_pass_set_blend_constant(&mut pass_data.pass, color) + { self.handle_error( &pass_data.error_sink, cause, @@ -3063,9 +3090,9 @@ impl crate::Context for ContextWgpuCore { width: u32, height: u32, ) { - if let Err(cause) = pass_data - .pass - .set_scissor_rect(&self.0, x, y, width, height) + if let Err(cause) = + self.0 + .render_pass_set_scissor_rect(&mut pass_data.pass, x, y, width, height) { self.handle_error( &pass_data.error_sink, @@ -3087,10 +3114,15 @@ impl crate::Context for ContextWgpuCore { min_depth: f32, max_depth: f32, ) { - if let Err(cause) = pass_data - .pass - .set_viewport(&self.0, x, y, width, height, min_depth, max_depth) - { + if let Err(cause) = self.0.render_pass_set_viewport( + &mut pass_data.pass, + x, + y, + width, + height, + min_depth, + max_depth, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -3106,7 +3138,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::RenderPassData, reference: u32, ) { - if let Err(cause) = pass_data.pass.set_stencil_reference(&self.0, reference) { + if let Err(cause) = self + .0 + .render_pass_set_stencil_reference(&mut pass_data.pass, reference) + { self.handle_error( &pass_data.error_sink, cause, @@ -3122,7 +3157,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::RenderPassData, label: &str, ) { - if let Err(cause) = pass_data.pass.insert_debug_marker(&self.0, label, 0) { + if let Err(cause) = self + .0 + .render_pass_insert_debug_marker(&mut pass_data.pass, label, 0) + { self.handle_error( &pass_data.error_sink, cause, @@ -3138,7 +3176,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::RenderPassData, group_label: &str, ) { - if let Err(cause) = pass_data.pass.push_debug_group(&self.0, group_label, 0) { + if let Err(cause) = self + .0 + .render_pass_push_debug_group(&mut pass_data.pass, group_label, 0) + { self.handle_error( &pass_data.error_sink, cause, @@ -3153,7 +3194,7 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::RenderPassId, pass_data: &mut Self::RenderPassData, ) { - if let Err(cause) = pass_data.pass.pop_debug_group(&self.0) { + if let Err(cause) = self.0.render_pass_pop_debug_group(&mut pass_data.pass) { self.handle_error( &pass_data.error_sink, cause, @@ -3171,9 +3212,9 @@ impl crate::Context for ContextWgpuCore { _query_set_data: &Self::QuerySetData, query_index: u32, ) { - if let Err(cause) = pass_data - .pass - .write_timestamp(&self.0, *query_set, query_index) + if let Err(cause) = + self.0 + .render_pass_write_timestamp(&mut pass_data.pass, *query_set, query_index) { self.handle_error( &pass_data.error_sink, @@ -3190,7 +3231,10 @@ impl crate::Context for ContextWgpuCore { pass_data: &mut Self::RenderPassData, query_index: u32, ) { - if let Err(cause) = pass_data.pass.begin_occlusion_query(&self.0, query_index) { + if let Err(cause) = self + .0 + .render_pass_begin_occlusion_query(&mut pass_data.pass, query_index) + { self.handle_error( &pass_data.error_sink, cause, @@ -3205,7 +3249,7 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::RenderPassId, pass_data: &mut Self::RenderPassData, ) { - if let Err(cause) = pass_data.pass.end_occlusion_query(&self.0) { + if let Err(cause) = self.0.render_pass_end_occlusion_query(&mut pass_data.pass) { self.handle_error( &pass_data.error_sink, cause, @@ -3223,11 +3267,11 @@ impl crate::Context for ContextWgpuCore { _query_set_data: &Self::QuerySetData, query_index: u32, ) { - if let Err(cause) = - pass_data - .pass - .begin_pipeline_statistics_query(&self.0, *query_set, query_index) - { + if let Err(cause) = self.0.render_pass_begin_pipeline_statistics_query( + &mut pass_data.pass, + *query_set, + query_index, + ) { self.handle_error( &pass_data.error_sink, cause, @@ -3242,7 +3286,10 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::RenderPassId, pass_data: &mut Self::RenderPassData, ) { - if let Err(cause) = pass_data.pass.end_pipeline_statistics_query(&self.0) { + if let Err(cause) = self + .0 + .render_pass_end_pipeline_statistics_query(&mut pass_data.pass) + { self.handle_error( &pass_data.error_sink, cause, @@ -3259,9 +3306,9 @@ impl crate::Context for ContextWgpuCore { render_bundles: &mut dyn Iterator, ) { let temp_render_bundles = render_bundles.map(|(i, _)| i).collect::>(); - if let Err(cause) = pass_data - .pass - .execute_bundles(&self.0, &temp_render_bundles) + if let Err(cause) = self + .0 + .render_pass_execute_bundles(&mut pass_data.pass, &temp_render_bundles) { self.handle_error( &pass_data.error_sink, @@ -3277,7 +3324,7 @@ impl crate::Context for ContextWgpuCore { _pass: &mut Self::RenderPassId, pass_data: &mut Self::RenderPassData, ) { - if let Err(cause) = pass_data.pass.end(&self.0) { + if let Err(cause) = self.0.render_pass_end(&mut pass_data.pass) { self.handle_error( &pass_data.error_sink, cause, From dc38de755a4d075663378c0e516d85d308d92282 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 10 Aug 2024 12:54:50 +0200 Subject: [PATCH 52/53] re-enable docs for wgpu-core --- wgpu-core/src/lib.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index ea7960fa57..ccbe64d527 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -2,20 +2,6 @@ //! It is designed for integration into browsers, as well as wrapping //! into other language-specific user-friendly libraries. //! -#![cfg_attr( - not(any(not(doc), wgpu_core_doc)), - doc = r#"\ -## Documentation hidden - -As a workaround for [an issue in rustdoc](https://github.com/rust-lang/rust/issues/114891) -that [affects `wgpu-core` documentation builds \ -severely](https://github.com/gfx-rs/wgpu/issues/4905), -the documentation for `wgpu-core` is empty unless built with -`RUSTFLAGS="--cfg wgpu_core_doc"`, which may take a very long time. -"# -)] -#![cfg(any(not(doc), wgpu_core_doc))] -//! //! ## Feature flags #![doc = document_features::document_features!()] //! From eb02613044f3b53a03aa3671d8b5e12438e1a9ac Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Sat, 10 Aug 2024 23:00:38 +0200 Subject: [PATCH 53/53] changelog entry --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f0366ea2c..fb1bc4a0ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,22 @@ Bottom level categories: ## Unreleased +### Major Changes + +#### `wgpu-core` is no longer generic over `wgpu-hal` backends +Dynamic dispatch between different backends has been moved from the user facing `wgpu` crate, +to a new dynamic dispatch mechanism inside the backend abstraction layer `wgpu-hal`. + +Whenever targeting more than a single backend (default on Windows & Linux) this leads to faster compile times and smaller binaries! +This also solves a long standing issue with `cargo doc` failing to run for `wgpu-core`. + +Benchmarking indicated that compute pass recording is slower as a consequence, +whereas on render passes speed improvements have been observed. +However, this effort simplifies many of the internals of the wgpu family of crates +which we're hoping to build performance improvements upon in the future. + +By @wumpf in [#6069](https://github.com/gfx-rs/wgpu/pull/6069), [#6099](https://github.com/gfx-rs/wgpu/pull/6099), [#6100](https://github.com/gfx-rs/wgpu/pull/6100). + ### New Features #### Naga