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, ProgrammableStage, TextureBinding,
27};
28
29pub trait DynResource: Any + WasmNotSendSync + 'static {
31 fn as_any(&self) -> &dyn Any;
32 fn as_any_mut(&mut self) -> &mut dyn Any;
33}
34
35macro_rules! impl_dyn_resource {
37 ($($type:ty),*) => {
38 $(
39 impl crate::DynResource for $type {
40 fn as_any(&self) -> &dyn ::core::any::Any {
41 self
42 }
43
44 fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any {
45 self
46 }
47 }
48 )*
49 };
50}
51pub(crate) use impl_dyn_resource;
52
53trait DynResourceExt {
55 fn expect_downcast_ref<T: DynResource>(&self) -> &T;
59 fn expect_downcast_mut<T: DynResource>(&mut self) -> &mut T;
63
64 unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T;
70}
71
72impl<R: DynResource + ?Sized> DynResourceExt for R {
73 fn expect_downcast_ref<'a, T: DynResource>(&'a self) -> &'a T {
74 self.as_any()
75 .downcast_ref()
76 .expect("Resource doesn't have the expected backend type.")
77 }
78
79 fn expect_downcast_mut<'a, T: DynResource>(&'a mut self) -> &'a mut T {
80 self.as_any_mut()
81 .downcast_mut()
82 .expect("Resource doesn't have the expected backend type.")
83 }
84
85 unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T {
86 debug_assert!(
87 <Self as Any>::type_id(self.as_ref()) == TypeId::of::<T>(),
88 "Resource doesn't have the expected type, expected {:?}, got {:?}",
89 TypeId::of::<T>(),
90 <Self as Any>::type_id(self.as_ref())
91 );
92
93 let casted_ptr = Box::into_raw(self).cast::<T>();
94 *unsafe { Box::from_raw(casted_ptr) }
104 }
105}
106
107pub trait DynAccelerationStructure: DynResource + fmt::Debug {}
108pub trait DynBindGroup: DynResource + fmt::Debug {}
109pub trait DynBindGroupLayout: DynResource + fmt::Debug {}
110pub trait DynBuffer: DynResource + fmt::Debug {}
111pub trait DynCommandBuffer: DynResource + fmt::Debug {}
112pub trait DynComputePipeline: DynResource + fmt::Debug {}
113pub trait DynFence: DynResource + fmt::Debug {}
114pub trait DynPipelineCache: DynResource + fmt::Debug {}
115pub trait DynPipelineLayout: DynResource + fmt::Debug {}
116pub trait DynQuerySet: DynResource + fmt::Debug {}
117pub trait DynRenderPipeline: DynResource + fmt::Debug {}
118pub trait DynSampler: DynResource + fmt::Debug {}
119pub trait DynShaderModule: DynResource + fmt::Debug {}
120pub trait DynSurfaceTexture:
121 DynResource + core::borrow::Borrow<dyn DynTexture> + fmt::Debug
122{
123}
124pub trait DynTexture: DynResource + fmt::Debug {}
125pub trait DynTextureView: DynResource + fmt::Debug {}
126
127impl<'a> BufferBinding<'a, dyn DynBuffer> {
128 pub fn expect_downcast<B: DynBuffer>(self) -> BufferBinding<'a, B> {
129 BufferBinding {
130 buffer: self.buffer.expect_downcast_ref(),
131 offset: self.offset,
132 size: self.size,
133 }
134 }
135}
136
137impl<'a> TextureBinding<'a, dyn DynTextureView> {
138 pub fn expect_downcast<T: DynTextureView>(self) -> TextureBinding<'a, T> {
139 TextureBinding {
140 view: self.view.expect_downcast_ref(),
141 usage: self.usage,
142 }
143 }
144}
145
146impl<'a> ProgrammableStage<'a, dyn DynShaderModule> {
147 fn expect_downcast<T: DynShaderModule>(self) -> ProgrammableStage<'a, T> {
148 ProgrammableStage {
149 module: self.module.expect_downcast_ref(),
150 entry_point: self.entry_point,
151 constants: self.constants,
152 zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory,
153 }
154 }
155}
156
157impl<'a> AccelerationStructureEntries<'a, dyn DynBuffer> {
158 fn expect_downcast<B: DynBuffer>(&self) -> AccelerationStructureEntries<'a, B> {
159 match self {
160 AccelerationStructureEntries::Instances(instances) => {
161 AccelerationStructureEntries::Instances(AccelerationStructureInstances {
162 buffer: instances.buffer.map(|b| b.expect_downcast_ref()),
163 offset: instances.offset,
164 count: instances.count,
165 })
166 }
167 AccelerationStructureEntries::Triangles(triangles) => {
168 AccelerationStructureEntries::Triangles(
169 triangles
170 .iter()
171 .map(|t| AccelerationStructureTriangles {
172 vertex_buffer: t.vertex_buffer.map(|b| b.expect_downcast_ref()),
173 vertex_format: t.vertex_format,
174 first_vertex: t.first_vertex,
175 vertex_count: t.vertex_count,
176 vertex_stride: t.vertex_stride,
177 indices: t.indices.as_ref().map(|i| {
178 AccelerationStructureTriangleIndices {
179 buffer: i.buffer.map(|b| b.expect_downcast_ref()),
180 format: i.format,
181 offset: i.offset,
182 count: i.count,
183 }
184 }),
185 transform: t.transform.as_ref().map(|t| {
186 AccelerationStructureTriangleTransform {
187 buffer: t.buffer.expect_downcast_ref(),
188 offset: t.offset,
189 }
190 }),
191 flags: t.flags,
192 })
193 .collect(),
194 )
195 }
196 AccelerationStructureEntries::AABBs(entries) => AccelerationStructureEntries::AABBs(
197 entries
198 .iter()
199 .map(|e| AccelerationStructureAABBs {
200 buffer: e.buffer.map(|b| b.expect_downcast_ref()),
201 offset: e.offset,
202 count: e.count,
203 stride: e.stride,
204 flags: e.flags,
205 })
206 .collect(),
207 ),
208 }
209 }
210}