1use crate::types::*;
2use dawn_rs::*;
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum WgpuCompatError {
7 #[error("wgpu object is not a custom backend")]
8 NotCustomBackend,
9 #[error("wgpu custom backend is not dawn-rs")]
10 NotDawnBackend,
11}
12
13#[derive(Debug, Clone)]
14pub struct Compat<T>(T);
15
16impl<T> Compat<T> {
17 pub fn into_inner(self) -> T {
18 self.0
19 }
20}
21
22impl<T> From<T> for Compat<T> {
23 fn from(value: T) -> Self {
24 Self(value)
25 }
26}
27
28#[derive(Debug, Clone)]
29pub struct CompatTexture<'a> {
30 texture: Texture,
31 desc: &'a wgpu::TextureDescriptor<'a>,
32}
33
34impl<'a> CompatTexture<'a> {
35 pub fn new(texture: Texture, desc: &'a wgpu::TextureDescriptor<'a>) -> Self {
36 Self { texture, desc }
37 }
38}
39
40impl From<Compat<Instance>> for wgpu::Instance {
41 fn from(value: Compat<Instance>) -> Self {
42 wgpu::Instance::from_custom(DawnInstance::from_instance(value.0))
43 }
44}
45
46impl TryFrom<&wgpu::Instance> for Compat<Instance> {
47 type Error = WgpuCompatError;
48
49 fn try_from(value: &wgpu::Instance) -> Result<Self, Self::Error> {
50 value
51 .as_custom::<DawnInstance>()
52 .map(|i| Compat(i.inner.get()))
53 .ok_or(WgpuCompatError::NotDawnBackend)
54 }
55}
56
57impl From<Compat<Adapter>> for wgpu::Adapter {
58 fn from(value: Compat<Adapter>) -> Self {
59 wgpu::Adapter::from_custom(DawnAdapter {
60 inner: SendSync::new(value.0),
61 })
62 }
63}
64
65impl TryFrom<&wgpu::Adapter> for Compat<Adapter> {
66 type Error = WgpuCompatError;
67
68 fn try_from(value: &wgpu::Adapter) -> Result<Self, Self::Error> {
69 value
70 .as_custom::<DawnAdapter>()
71 .map(|a| Compat(a.inner.get()))
72 .ok_or(WgpuCompatError::NotDawnBackend)
73 }
74}
75
76impl From<Compat<Device>> for wgpu::Device {
77 fn from(value: Compat<Device>) -> Self {
78 wgpu::Device::from_custom(DawnDevice { inner: value.0 })
79 }
80}
81
82impl TryFrom<&wgpu::Device> for Compat<Device> {
83 type Error = WgpuCompatError;
84
85 fn try_from(value: &wgpu::Device) -> Result<Self, Self::Error> {
86 value
87 .as_custom::<DawnDevice>()
88 .map(|d| Compat(d.inner.clone()))
89 .ok_or(WgpuCompatError::NotDawnBackend)
90 }
91}
92
93impl From<Compat<Queue>> for wgpu::Queue {
94 fn from(value: Compat<Queue>) -> Self {
95 wgpu::Queue::from_custom(DawnQueue { inner: value.0 })
96 }
97}
98
99impl TryFrom<&wgpu::Queue> for Compat<Queue> {
100 type Error = WgpuCompatError;
101
102 fn try_from(value: &wgpu::Queue) -> Result<Self, Self::Error> {
103 value
104 .as_custom::<DawnQueue>()
105 .map(|q| Compat(q.inner.clone()))
106 .ok_or(WgpuCompatError::NotDawnBackend)
107 }
108}
109
110impl From<CompatTexture<'_>> for wgpu::Texture {
111 fn from(value: CompatTexture<'_>) -> Self {
112 wgpu::Texture::from_custom(
113 DawnTexture {
114 inner: value.texture,
115 },
116 value.desc,
117 )
118 }
119}
120
121impl TryFrom<&wgpu::Texture> for Compat<Texture> {
122 type Error = WgpuCompatError;
123
124 fn try_from(value: &wgpu::Texture) -> Result<Self, Self::Error> {
125 value
126 .as_custom::<DawnTexture>()
127 .map(|t| Compat(t.inner.clone()))
128 .ok_or(WgpuCompatError::NotDawnBackend)
129 }
130}
131
132impl TryFrom<&wgpu::Surface<'_>> for Compat<Surface> {
133 type Error = WgpuCompatError;
134
135 fn try_from(value: &wgpu::Surface<'_>) -> Result<Self, Self::Error> {
136 value
137 .as_custom::<DawnSurface>()
138 .map(|s| Compat(s.inner.get()))
139 .ok_or(WgpuCompatError::NotDawnBackend)
140 }
141}
142
143impl TryFrom<&wgpu::Buffer> for Compat<Buffer> {
144 type Error = WgpuCompatError;
145
146 fn try_from(value: &wgpu::Buffer) -> Result<Self, Self::Error> {
147 value
148 .as_custom::<DawnBuffer>()
149 .map(|b| Compat(b.inner.clone()))
150 .ok_or(WgpuCompatError::NotDawnBackend)
151 }
152}
153
154impl TryFrom<&wgpu::TextureView> for Compat<TextureView> {
155 type Error = WgpuCompatError;
156
157 fn try_from(value: &wgpu::TextureView) -> Result<Self, Self::Error> {
158 value
159 .as_custom::<DawnTextureView>()
160 .map(|v| Compat(v.inner.clone()))
161 .ok_or(WgpuCompatError::NotDawnBackend)
162 }
163}
164
165impl TryFrom<&wgpu::Sampler> for Compat<Sampler> {
166 type Error = WgpuCompatError;
167
168 fn try_from(value: &wgpu::Sampler) -> Result<Self, Self::Error> {
169 value
170 .as_custom::<DawnSampler>()
171 .map(|s| Compat(s.inner.clone()))
172 .ok_or(WgpuCompatError::NotDawnBackend)
173 }
174}
175
176impl TryFrom<&wgpu::BindGroupLayout> for Compat<BindGroupLayout> {
177 type Error = WgpuCompatError;
178
179 fn try_from(value: &wgpu::BindGroupLayout) -> Result<Self, Self::Error> {
180 value
181 .as_custom::<DawnBindGroupLayout>()
182 .map(|l| Compat(l.inner.clone()))
183 .ok_or(WgpuCompatError::NotDawnBackend)
184 }
185}
186
187impl TryFrom<&wgpu::BindGroup> for Compat<BindGroup> {
188 type Error = WgpuCompatError;
189
190 fn try_from(value: &wgpu::BindGroup) -> Result<Self, Self::Error> {
191 value
192 .as_custom::<DawnBindGroup>()
193 .map(|g| Compat(g.inner.clone()))
194 .ok_or(WgpuCompatError::NotDawnBackend)
195 }
196}
197
198impl TryFrom<&wgpu::PipelineLayout> for Compat<PipelineLayout> {
199 type Error = WgpuCompatError;
200
201 fn try_from(value: &wgpu::PipelineLayout) -> Result<Self, Self::Error> {
202 value
203 .as_custom::<DawnPipelineLayout>()
204 .map(|l| Compat(l.inner.clone()))
205 .ok_or(WgpuCompatError::NotDawnBackend)
206 }
207}
208
209impl TryFrom<&wgpu::RenderPipeline> for Compat<RenderPipeline> {
210 type Error = WgpuCompatError;
211
212 fn try_from(value: &wgpu::RenderPipeline) -> Result<Self, Self::Error> {
213 value
214 .as_custom::<DawnRenderPipeline>()
215 .map(|p| Compat(p.inner.clone()))
216 .ok_or(WgpuCompatError::NotDawnBackend)
217 }
218}
219
220impl TryFrom<&wgpu::ComputePipeline> for Compat<ComputePipeline> {
221 type Error = WgpuCompatError;
222
223 fn try_from(value: &wgpu::ComputePipeline) -> Result<Self, Self::Error> {
224 value
225 .as_custom::<DawnComputePipeline>()
226 .map(|p| Compat(p.inner.clone()))
227 .ok_or(WgpuCompatError::NotDawnBackend)
228 }
229}
230
231impl TryFrom<&wgpu::ShaderModule> for Compat<ShaderModule> {
232 type Error = WgpuCompatError;
233
234 fn try_from(value: &wgpu::ShaderModule) -> Result<Self, Self::Error> {
235 value
236 .as_custom::<DawnShaderModule>()
237 .map(|m| Compat(m.inner.clone()))
238 .ok_or(WgpuCompatError::NotDawnBackend)
239 }
240}
241
242impl TryFrom<&wgpu::CommandEncoder> for Compat<CommandEncoder> {
243 type Error = WgpuCompatError;
244
245 fn try_from(value: &wgpu::CommandEncoder) -> Result<Self, Self::Error> {
246 value
247 .as_custom::<DawnCommandEncoder>()
248 .map(|e| Compat(e.inner.get()))
249 .ok_or(WgpuCompatError::NotDawnBackend)
250 }
251}
252
253impl TryFrom<&wgpu::CommandBuffer> for Compat<CommandBuffer> {
254 type Error = WgpuCompatError;
255
256 fn try_from(value: &wgpu::CommandBuffer) -> Result<Self, Self::Error> {
257 value
258 .as_custom::<DawnCommandBuffer>()
259 .map(|b| Compat(b.inner.clone()))
260 .ok_or(WgpuCompatError::NotDawnBackend)
261 }
262}
263
264impl TryFrom<&wgpu::RenderBundle> for Compat<RenderBundle> {
265 type Error = WgpuCompatError;
266
267 fn try_from(value: &wgpu::RenderBundle) -> Result<Self, Self::Error> {
268 value
269 .as_custom::<DawnRenderBundle>()
270 .map(|b| Compat(b.inner.clone()))
271 .ok_or(WgpuCompatError::NotDawnBackend)
272 }
273}
274
275impl TryFrom<&wgpu::QuerySet> for Compat<QuerySet> {
276 type Error = WgpuCompatError;
277
278 fn try_from(value: &wgpu::QuerySet) -> Result<Self, Self::Error> {
279 value
280 .as_custom::<DawnQuerySet>()
281 .map(|q| Compat(q.inner.clone()))
282 .ok_or(WgpuCompatError::NotDawnBackend)
283 }
284}