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