wgpu_hal/dynamic/
mod.rs
1mod adapter;
2mod command;
3mod device;
4mod instance;
5mod queue;
6mod surface;
7
8pub use adapter::{DynAdapter, DynOpenDevice};
9pub use command::DynCommandEncoder;
10pub use device::DynDevice;
11pub use instance::{DynExposedAdapter, DynInstance};
12pub use queue::DynQueue;
13pub use surface::{DynAcquiredSurfaceTexture, DynSurface};
14
15use alloc::boxed::Box;
16use core::{
17 any::{Any, TypeId},
18 fmt,
19};
20
21use wgt::WasmNotSendSync;
22
23use crate::{
24 AccelerationStructureAABBs, AccelerationStructureEntries, AccelerationStructureInstances,
25 AccelerationStructureTriangleIndices, AccelerationStructureTriangleTransform,
26 AccelerationStructureTriangles, BufferBinding, ExternalTextureBinding, ProgrammableStage,
27 TextureBinding,
28};
29
30pub trait DynResource: Any + WasmNotSendSync + 'static {
32 fn as_any(&self) -> &dyn Any;
33 fn as_any_mut(&mut self) -> &mut dyn Any;
34}
35
36macro_rules! impl_dyn_resource {
38 ($($type:ty),*) => {
39 $(
40 impl crate::DynResource for $type {
41 fn as_any(&self) -> &dyn ::core::any::Any {
42 self
43 }
44
45 fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any {
46 self
47 }
48 }
49 )*
50 };
51}
52pub(crate) use impl_dyn_resource;
53
54trait DynResourceExt {
56 fn expect_downcast_ref<T: DynResource>(&self) -> &T;
60 fn expect_downcast_mut<T: DynResource>(&mut self) -> &mut T;
64
65 unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T;
71}
72
73impl<R: DynResource + ?Sized> DynResourceExt for R {
74 fn expect_downcast_ref<'a, T: DynResource>(&'a self) -> &'a T {
75 self.as_any()
76 .downcast_ref()
77 .expect("Resource doesn't have the expected backend type.")
78 }
79
80 fn expect_downcast_mut<'a, T: DynResource>(&'a mut self) -> &'a mut T {
81 self.as_any_mut()
82 .downcast_mut()
83 .expect("Resource doesn't have the expected backend type.")
84 }
85
86 unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T {
87 debug_assert!(
88 <Self as Any>::type_id(self.as_ref()) == TypeId::of::<T>(),
89 "Resource doesn't have the expected type, expected {:?}, got {:?}",
90 TypeId::of::<T>(),
91 <Self as Any>::type_id(self.as_ref())
92 );
93
94 let casted_ptr = Box::into_raw(self).cast::<T>();
95 *unsafe { Box::from_raw(casted_ptr) }
105 }
106}
107
108pub trait DynAccelerationStructure: DynResource + fmt::Debug {}
109pub trait DynBindGroup: DynResource + fmt::Debug {}
110pub trait DynBindGroupLayout: DynResource + fmt::Debug {}
111pub trait DynBuffer: DynResource + fmt::Debug {}
112pub trait DynCommandBuffer: DynResource + fmt::Debug {}
113pub trait DynComputePipeline: DynResource + fmt::Debug {}
114pub trait DynFence: DynResource + fmt::Debug {}
115pub trait DynPipelineCache: DynResource + fmt::Debug {}
116pub trait DynPipelineLayout: DynResource + fmt::Debug {}
117pub trait DynQuerySet: DynResource + fmt::Debug {}
118pub trait DynRenderPipeline: DynResource + fmt::Debug {}
119pub trait DynSampler: DynResource + fmt::Debug {}
120pub trait DynShaderModule: DynResource + fmt::Debug {}
121pub trait DynSurfaceTexture:
122 DynResource + core::borrow::Borrow<dyn DynTexture> + fmt::Debug
123{
124}
125pub trait DynTexture: DynResource + fmt::Debug {}
126pub trait DynTextureView: DynResource + fmt::Debug {}
127
128impl<'a> BufferBinding<'a, dyn DynBuffer> {
129 pub fn expect_downcast<B: DynBuffer>(self) -> BufferBinding<'a, B> {
130 BufferBinding {
131 buffer: self.buffer.expect_downcast_ref(),
132 offset: self.offset,
133 size: self.size,
134 }
135 }
136}
137
138impl<'a> TextureBinding<'a, dyn DynTextureView> {
139 pub fn expect_downcast<T: DynTextureView>(self) -> TextureBinding<'a, T> {
140 TextureBinding {
141 view: self.view.expect_downcast_ref(),
142 usage: self.usage,
143 }
144 }
145}
146
147impl<'a> ExternalTextureBinding<'a, dyn DynBuffer, dyn DynTextureView> {
148 pub fn expect_downcast<B: DynBuffer, T: DynTextureView>(
149 self,
150 ) -> ExternalTextureBinding<'a, B, T> {
151 let planes = self.planes.map(|plane| plane.expect_downcast());
152 let params = self.params.expect_downcast();
153 ExternalTextureBinding { planes, params }
154 }
155}
156
157impl<'a> ProgrammableStage<'a, dyn DynShaderModule> {
158 fn expect_downcast<T: DynShaderModule>(self) -> ProgrammableStage<'a, T> {
159 ProgrammableStage {
160 module: self.module.expect_downcast_ref(),
161 entry_point: self.entry_point,
162 constants: self.constants,
163 zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory,
164 }
165 }
166}
167
168impl<'a> AccelerationStructureEntries<'a, dyn DynBuffer> {
169 fn expect_downcast<B: DynBuffer>(&self) -> AccelerationStructureEntries<'a, B> {
170 match self {
171 AccelerationStructureEntries::Instances(instances) => {
172 AccelerationStructureEntries::Instances(AccelerationStructureInstances {
173 buffer: instances.buffer.map(|b| b.expect_downcast_ref()),
174 offset: instances.offset,
175 count: instances.count,
176 })
177 }
178 AccelerationStructureEntries::Triangles(triangles) => {
179 AccelerationStructureEntries::Triangles(
180 triangles
181 .iter()
182 .map(|t| AccelerationStructureTriangles {
183 vertex_buffer: t.vertex_buffer.map(|b| b.expect_downcast_ref()),
184 vertex_format: t.vertex_format,
185 first_vertex: t.first_vertex,
186 vertex_count: t.vertex_count,
187 vertex_stride: t.vertex_stride,
188 indices: t.indices.as_ref().map(|i| {
189 AccelerationStructureTriangleIndices {
190 buffer: i.buffer.map(|b| b.expect_downcast_ref()),
191 format: i.format,
192 offset: i.offset,
193 count: i.count,
194 }
195 }),
196 transform: t.transform.as_ref().map(|t| {
197 AccelerationStructureTriangleTransform {
198 buffer: t.buffer.expect_downcast_ref(),
199 offset: t.offset,
200 }
201 }),
202 flags: t.flags,
203 })
204 .collect(),
205 )
206 }
207 AccelerationStructureEntries::AABBs(entries) => AccelerationStructureEntries::AABBs(
208 entries
209 .iter()
210 .map(|e| AccelerationStructureAABBs {
211 buffer: e.buffer.map(|b| b.expect_downcast_ref()),
212 offset: e.offset,
213 count: e.count,
214 stride: e.stride,
215 flags: e.flags,
216 })
217 .collect(),
218 ),
219 }
220 }
221}