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