1#![allow(unexpected_cfgs, dead_code, unreachable_patterns)]
2
3use dawn_rs::*;
4use std::fmt;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::{Arc, Mutex};
8use std::task::{Context, Poll, Waker};
9
10use wgpu::custom::*;
11
12#[derive(Debug)]
13pub enum WgpuCompatError {
14 NotCustomBackend,
15 NotDawnBackend,
16}
17
18impl fmt::Display for WgpuCompatError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 WgpuCompatError::NotCustomBackend => write!(f, "wgpu object is not a custom backend"),
22 WgpuCompatError::NotDawnBackend => write!(f, "wgpu custom backend is not dawn-rs"),
23 }
24 }
25}
26
27impl std::error::Error for WgpuCompatError {}
28
29#[derive(Debug, Clone)]
30struct DawnInstance {
31 inner: Instance,
32}
33
34#[derive(Debug, Clone)]
35struct DawnAdapter {
36 inner: Adapter,
37}
38
39#[derive(Debug, Clone)]
40struct DawnDevice {
41 inner: Device,
42}
43
44#[derive(Debug, Clone)]
45struct DawnQueue {
46 inner: Queue,
47}
48
49#[derive(Debug, Clone)]
50struct DawnShaderModule {
51 inner: ShaderModule,
52}
53
54#[derive(Debug, Clone)]
55struct DawnBindGroupLayout {
56 inner: BindGroupLayout,
57}
58
59#[derive(Debug, Clone)]
60struct DawnBindGroup {
61 inner: BindGroup,
62}
63
64#[derive(Debug, Clone)]
65struct DawnTextureView {
66 inner: TextureView,
67}
68
69#[derive(Debug, Clone)]
70struct DawnSampler {
71 inner: Sampler,
72}
73
74#[derive(Debug, Clone)]
75struct DawnBuffer {
76 inner: Buffer,
77}
78
79#[derive(Debug, Clone)]
80struct DawnTexture {
81 inner: Texture,
82}
83
84#[derive(Debug, Clone)]
85struct DawnExternalTexture {
86 inner: ExternalTexture,
87}
88
89#[derive(Debug, Clone)]
90struct DawnQuerySet {
91 inner: QuerySet,
92}
93
94#[derive(Debug, Clone)]
95struct DawnPipelineLayout {
96 inner: PipelineLayout,
97}
98
99#[derive(Debug, Clone)]
100struct DawnRenderPipeline {
101 inner: RenderPipeline,
102}
103
104#[derive(Debug, Clone)]
105struct DawnComputePipeline {
106 inner: ComputePipeline,
107}
108
109#[derive(Debug)]
110struct DawnCommandEncoder {
111 inner: CommandEncoder,
112}
113
114#[derive(Debug)]
115struct DawnComputePass {
116 inner: ComputePassEncoder,
117 ended: bool,
118}
119
120#[derive(Debug)]
121struct DawnRenderPass {
122 inner: RenderPassEncoder,
123 ended: bool,
124}
125
126#[derive(Debug)]
127struct DawnCommandBuffer {
128 inner: CommandBuffer,
129}
130
131#[derive(Debug)]
132struct DawnRenderBundleEncoder {
133 inner: RenderBundleEncoder,
134}
135
136#[derive(Debug, Clone)]
137struct DawnRenderBundle {
138 inner: RenderBundle,
139}
140
141#[cfg(target_os = "macos")]
142#[derive(Debug)]
143struct MetalLayerHandle {
144 ptr: *mut std::ffi::c_void,
145}
146
147#[cfg(target_os = "macos")]
148unsafe impl Send for MetalLayerHandle {}
149#[cfg(target_os = "macos")]
150unsafe impl Sync for MetalLayerHandle {}
151
152#[cfg(target_os = "macos")]
153impl Drop for MetalLayerHandle {
154 fn drop(&mut self) {
155 if self.ptr.is_null() {
156 return;
157 }
158 unsafe {
159 let ptr = self.ptr.cast::<objc2_quartz_core::CAMetalLayer>();
160 let _ = objc2::rc::Retained::from_raw(ptr);
161 }
162 }
163}
164
165#[derive(Debug, Clone)]
166struct DawnSurface {
167 inner: Surface,
168 #[cfg(target_os = "macos")]
169 metal_layer: Option<Arc<MetalLayerHandle>>,
170}
171
172#[derive(Debug, Clone)]
173struct DawnSurfaceOutputDetail {
174 surface: Surface,
175}
176
177#[derive(Debug)]
178struct DawnQueueWriteBuffer {
179 inner: Vec<u8>,
180}
181
182#[derive(Debug)]
183struct DawnBufferMappedRange {
184 data: *mut u8,
185 size: usize,
186}
187
188#[derive(Debug)]
189struct DawnPipelineCache;
190
191#[derive(Debug)]
192struct DawnBlas;
193
194#[derive(Debug)]
195struct DawnTlas;
196
197#[derive(Debug)]
198struct DawnError(String);
199
200impl fmt::Display for DawnError {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 write!(f, "{}", self.0)
203 }
204}
205
206impl std::error::Error for DawnError {}
207
208macro_rules! unsafe_send_sync {
209 ($($ty:ty),+ $(,)?) => {
210 $(unsafe impl Send for $ty {}
211 unsafe impl Sync for $ty {})+
212 };
213}
214
215unsafe_send_sync!(
216 DawnInstance,
217 DawnAdapter,
218 DawnDevice,
219 DawnQueue,
220 DawnShaderModule,
221 DawnBindGroupLayout,
222 DawnBindGroup,
223 DawnTextureView,
224 DawnSampler,
225 DawnBuffer,
226 DawnTexture,
227 DawnExternalTexture,
228 DawnQuerySet,
229 DawnPipelineLayout,
230 DawnRenderPipeline,
231 DawnComputePipeline,
232 DawnCommandEncoder,
233 DawnComputePass,
234 DawnRenderPass,
235 DawnCommandBuffer,
236 DawnRenderBundleEncoder,
237 DawnRenderBundle,
238 DawnSurface,
239 DawnSurfaceOutputDetail,
240 DawnQueueWriteBuffer,
241 DawnBufferMappedRange,
242 DawnPipelineCache,
243 DawnBlas,
244 DawnTlas,
245 DawnError,
246);
247
248struct CallbackFuture<T> {
249 shared: Arc<Mutex<CallbackShared<T>>>,
250}
251
252struct CallbackShared<T> {
253 result: Option<T>,
254 waker: Option<Waker>,
255}
256
257impl<T> CallbackFuture<T> {
258 fn new() -> (Self, Arc<Mutex<CallbackShared<T>>>) {
259 let shared = Arc::new(Mutex::new(CallbackShared {
260 result: None,
261 waker: None,
262 }));
263 (
264 Self {
265 shared: shared.clone(),
266 },
267 shared,
268 )
269 }
270}
271
272impl<T> Future for CallbackFuture<T> {
273 type Output = T;
274
275 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
276 let mut shared = self.shared.lock().expect("wgpu-compat future lock");
277 if let Some(result) = shared.result.take() {
278 return Poll::Ready(result);
279 }
280 shared.waker = Some(cx.waker().clone());
281 Poll::Pending
282 }
283}
284
285fn complete_shared<T>(shared: &Arc<Mutex<CallbackShared<T>>>, value: T) {
286 let mut shared = shared.lock().expect("wgpu-compat future lock");
287 shared.result = Some(value);
288 if let Some(waker) = shared.waker.take() {
289 waker.wake();
290 }
291}
292
293fn label_to_string(label: wgpu::Label<'_>) -> Option<String> {
294 label.map(|s| s.to_string())
295}
296
297fn map_backend_type_to_wgpu(value: BackendType) -> wgpu::Backend {
298 match value {
299 BackendType::Vulkan => wgpu::Backend::Vulkan,
300 BackendType::Metal => wgpu::Backend::Metal,
301 BackendType::D3D12 => wgpu::Backend::Dx12,
302 BackendType::D3D11 => wgpu::Backend::Noop,
303 BackendType::OpenGL | BackendType::OpenGLes => wgpu::Backend::Gl,
304 BackendType::WebGPU => wgpu::Backend::BrowserWebGpu,
305 _ => wgpu::Backend::Noop,
306 }
307}
308
309fn map_power_preference(value: wgpu::PowerPreference) -> PowerPreference {
310 match value {
311 wgpu::PowerPreference::None => PowerPreference::Undefined,
312 wgpu::PowerPreference::LowPower => PowerPreference::LowPower,
313 wgpu::PowerPreference::HighPerformance => PowerPreference::HighPerformance,
314 _ => PowerPreference::Undefined,
315 }
316}
317
318fn map_texture_format(value: wgpu::TextureFormat) -> TextureFormat {
319 use wgpu::TextureFormat as W;
320 match value {
321 W::R8Unorm => TextureFormat::R8Unorm,
322 W::R8Snorm => TextureFormat::R8Snorm,
323 W::R8Uint => TextureFormat::R8Uint,
324 W::R8Sint => TextureFormat::R8Sint,
325 W::R16Unorm => TextureFormat::R16Unorm,
326 W::R16Snorm => TextureFormat::R16Snorm,
327 W::R16Uint => TextureFormat::R16Uint,
328 W::R16Sint => TextureFormat::R16Sint,
329 W::R16Float => TextureFormat::R16Float,
330 W::Rg8Unorm => TextureFormat::Rg8Unorm,
331 W::Rg8Snorm => TextureFormat::Rg8Snorm,
332 W::Rg8Uint => TextureFormat::Rg8Uint,
333 W::Rg8Sint => TextureFormat::Rg8Sint,
334 W::R32Float => TextureFormat::R32Float,
335 W::R32Uint => TextureFormat::R32Uint,
336 W::R32Sint => TextureFormat::R32Sint,
337 W::Rg16Unorm => TextureFormat::Rg16Unorm,
338 W::Rg16Snorm => TextureFormat::Rg16Snorm,
339 W::Rg16Uint => TextureFormat::Rg16Uint,
340 W::Rg16Sint => TextureFormat::Rg16Sint,
341 W::Rg16Float => TextureFormat::Rg16Float,
342 W::Rgba8Unorm => TextureFormat::Rgba8Unorm,
343 W::Rgba8UnormSrgb => TextureFormat::Rgba8UnormSrgb,
344 W::Rgba8Snorm => TextureFormat::Rgba8Snorm,
345 W::Rgba8Uint => TextureFormat::Rgba8Uint,
346 W::Rgba8Sint => TextureFormat::Rgba8Sint,
347 W::Bgra8Unorm => TextureFormat::Bgra8Unorm,
348 W::Bgra8UnormSrgb => TextureFormat::Bgra8UnormSrgb,
349 W::Rgb10a2Unorm => TextureFormat::Rgb10A2Unorm,
350 W::Rgb10a2Uint => TextureFormat::Rgb10A2Uint,
351 W::Rg11b10Ufloat => TextureFormat::Rg11B10Ufloat,
352 W::Rgb9e5Ufloat => TextureFormat::Rgb9E5Ufloat,
353 W::Rg32Float => TextureFormat::Rg32Float,
354 W::Rg32Uint => TextureFormat::Rg32Uint,
355 W::Rg32Sint => TextureFormat::Rg32Sint,
356 W::Rgba16Unorm => TextureFormat::Rgba16Unorm,
357 W::Rgba16Snorm => TextureFormat::Rgba16Snorm,
358 W::Rgba16Uint => TextureFormat::Rgba16Uint,
359 W::Rgba16Sint => TextureFormat::Rgba16Sint,
360 W::Rgba16Float => TextureFormat::Rgba16Float,
361 W::Rgba32Float => TextureFormat::Rgba32Float,
362 W::Rgba32Uint => TextureFormat::Rgba32Uint,
363 W::Rgba32Sint => TextureFormat::Rgba32Sint,
364 W::Stencil8 => TextureFormat::Stencil8,
365 W::Depth16Unorm => TextureFormat::Depth16Unorm,
366 W::Depth24Plus => TextureFormat::Depth24Plus,
367 W::Depth24PlusStencil8 => TextureFormat::Depth24PlusStencil8,
368 W::Depth32Float => TextureFormat::Depth32Float,
369 W::Depth32FloatStencil8 => TextureFormat::Depth32FloatStencil8,
370 W::Bc1RgbaUnorm => TextureFormat::Bc1RgbaUnorm,
371 W::Bc1RgbaUnormSrgb => TextureFormat::Bc1RgbaUnormSrgb,
372 W::Bc2RgbaUnorm => TextureFormat::Bc2RgbaUnorm,
373 W::Bc2RgbaUnormSrgb => TextureFormat::Bc2RgbaUnormSrgb,
374 W::Bc3RgbaUnorm => TextureFormat::Bc3RgbaUnorm,
375 W::Bc3RgbaUnormSrgb => TextureFormat::Bc3RgbaUnormSrgb,
376 W::Bc4RUnorm => TextureFormat::Bc4RUnorm,
377 W::Bc4RSnorm => TextureFormat::Bc4RSnorm,
378 W::Bc5RgUnorm => TextureFormat::Bc5RgUnorm,
379 W::Bc5RgSnorm => TextureFormat::Bc5RgSnorm,
380 W::Bc6hRgbUfloat => TextureFormat::Bc6HRgbUfloat,
381 W::Bc6hRgbFloat => TextureFormat::Bc6HRgbFloat,
382 W::Bc7RgbaUnorm => TextureFormat::Bc7RgbaUnorm,
383 W::Bc7RgbaUnormSrgb => TextureFormat::Bc7RgbaUnormSrgb,
384 W::Etc2Rgb8Unorm => TextureFormat::Etc2Rgb8Unorm,
385 W::Etc2Rgb8UnormSrgb => TextureFormat::Etc2Rgb8UnormSrgb,
386 W::Etc2Rgb8A1Unorm => TextureFormat::Etc2Rgb8A1Unorm,
387 W::Etc2Rgb8A1UnormSrgb => TextureFormat::Etc2Rgb8A1UnormSrgb,
388 W::Etc2Rgba8Unorm => TextureFormat::Etc2Rgba8Unorm,
389 W::Etc2Rgba8UnormSrgb => TextureFormat::Etc2Rgba8UnormSrgb,
390 W::EacR11Unorm => TextureFormat::EacR11Unorm,
391 W::EacR11Snorm => TextureFormat::EacR11Snorm,
392 W::EacRg11Unorm => TextureFormat::EacRg11Unorm,
393 W::EacRg11Snorm => TextureFormat::EacRg11Snorm,
394 W::Astc { block, channel } => match (block, channel) {
395 (wgpu::AstcBlock::B4x4, wgpu::AstcChannel::Unorm) => TextureFormat::Astc4X4Unorm,
396 (wgpu::AstcBlock::B4x4, wgpu::AstcChannel::UnormSrgb) => {
397 TextureFormat::Astc4X4UnormSrgb
398 }
399 (wgpu::AstcBlock::B5x4, wgpu::AstcChannel::Unorm) => TextureFormat::Astc5X4Unorm,
400 (wgpu::AstcBlock::B5x4, wgpu::AstcChannel::UnormSrgb) => {
401 TextureFormat::Astc5X4UnormSrgb
402 }
403 (wgpu::AstcBlock::B5x5, wgpu::AstcChannel::Unorm) => TextureFormat::Astc5X5Unorm,
404 (wgpu::AstcBlock::B5x5, wgpu::AstcChannel::UnormSrgb) => {
405 TextureFormat::Astc5X5UnormSrgb
406 }
407 (wgpu::AstcBlock::B6x5, wgpu::AstcChannel::Unorm) => TextureFormat::Astc6X5Unorm,
408 (wgpu::AstcBlock::B6x5, wgpu::AstcChannel::UnormSrgb) => {
409 TextureFormat::Astc6X5UnormSrgb
410 }
411 (wgpu::AstcBlock::B6x6, wgpu::AstcChannel::Unorm) => TextureFormat::Astc6X6Unorm,
412 (wgpu::AstcBlock::B6x6, wgpu::AstcChannel::UnormSrgb) => {
413 TextureFormat::Astc6X6UnormSrgb
414 }
415 (wgpu::AstcBlock::B8x5, wgpu::AstcChannel::Unorm) => TextureFormat::Astc8X5Unorm,
416 (wgpu::AstcBlock::B8x5, wgpu::AstcChannel::UnormSrgb) => {
417 TextureFormat::Astc8X5UnormSrgb
418 }
419 (wgpu::AstcBlock::B8x6, wgpu::AstcChannel::Unorm) => TextureFormat::Astc8X6Unorm,
420 (wgpu::AstcBlock::B8x6, wgpu::AstcChannel::UnormSrgb) => {
421 TextureFormat::Astc8X6UnormSrgb
422 }
423 (wgpu::AstcBlock::B8x8, wgpu::AstcChannel::Unorm) => TextureFormat::Astc8X8Unorm,
424 (wgpu::AstcBlock::B8x8, wgpu::AstcChannel::UnormSrgb) => {
425 TextureFormat::Astc8X8UnormSrgb
426 }
427 (wgpu::AstcBlock::B10x5, wgpu::AstcChannel::Unorm) => TextureFormat::Astc10X5Unorm,
428 (wgpu::AstcBlock::B10x5, wgpu::AstcChannel::UnormSrgb) => {
429 TextureFormat::Astc10X5UnormSrgb
430 }
431 (wgpu::AstcBlock::B10x6, wgpu::AstcChannel::Unorm) => TextureFormat::Astc10X6Unorm,
432 (wgpu::AstcBlock::B10x6, wgpu::AstcChannel::UnormSrgb) => {
433 TextureFormat::Astc10X6UnormSrgb
434 }
435 (wgpu::AstcBlock::B10x8, wgpu::AstcChannel::Unorm) => TextureFormat::Astc10X8Unorm,
436 (wgpu::AstcBlock::B10x8, wgpu::AstcChannel::UnormSrgb) => {
437 TextureFormat::Astc10X8UnormSrgb
438 }
439 (wgpu::AstcBlock::B10x10, wgpu::AstcChannel::Unorm) => TextureFormat::Astc10X10Unorm,
440 (wgpu::AstcBlock::B10x10, wgpu::AstcChannel::UnormSrgb) => {
441 TextureFormat::Astc10X10UnormSrgb
442 }
443 (wgpu::AstcBlock::B12x10, wgpu::AstcChannel::Unorm) => TextureFormat::Astc12X10Unorm,
444 (wgpu::AstcBlock::B12x10, wgpu::AstcChannel::UnormSrgb) => {
445 TextureFormat::Astc12X10UnormSrgb
446 }
447 (wgpu::AstcBlock::B12x12, wgpu::AstcChannel::Unorm) => TextureFormat::Astc12X12Unorm,
448 (wgpu::AstcBlock::B12x12, wgpu::AstcChannel::UnormSrgb) => {
449 TextureFormat::Astc12X12UnormSrgb
450 }
451 _ => panic!("wgpu-compat: unsupported ASTC format"),
452 },
453 _ => panic!("wgpu-compat: unsupported texture format"),
454 }
455}
456
457fn map_texture_format_to_wgpu(value: TextureFormat) -> wgpu::TextureFormat {
458 use wgpu::TextureFormat as W;
459 match value {
460 TextureFormat::R8Unorm => W::R8Unorm,
461 TextureFormat::R8Snorm => W::R8Snorm,
462 TextureFormat::R8Uint => W::R8Uint,
463 TextureFormat::R8Sint => W::R8Sint,
464 TextureFormat::R16Unorm => W::R16Unorm,
465 TextureFormat::R16Snorm => W::R16Snorm,
466 TextureFormat::R16Uint => W::R16Uint,
467 TextureFormat::R16Sint => W::R16Sint,
468 TextureFormat::R16Float => W::R16Float,
469 TextureFormat::Rg8Unorm => W::Rg8Unorm,
470 TextureFormat::Rg8Snorm => W::Rg8Snorm,
471 TextureFormat::Rg8Uint => W::Rg8Uint,
472 TextureFormat::Rg8Sint => W::Rg8Sint,
473 TextureFormat::R32Float => W::R32Float,
474 TextureFormat::R32Uint => W::R32Uint,
475 TextureFormat::R32Sint => W::R32Sint,
476 TextureFormat::Rg16Unorm => W::Rg16Unorm,
477 TextureFormat::Rg16Snorm => W::Rg16Snorm,
478 TextureFormat::Rg16Uint => W::Rg16Uint,
479 TextureFormat::Rg16Sint => W::Rg16Sint,
480 TextureFormat::Rg16Float => W::Rg16Float,
481 TextureFormat::Rgba8Unorm => W::Rgba8Unorm,
482 TextureFormat::Rgba8UnormSrgb => W::Rgba8UnormSrgb,
483 TextureFormat::Rgba8Snorm => W::Rgba8Snorm,
484 TextureFormat::Rgba8Uint => W::Rgba8Uint,
485 TextureFormat::Rgba8Sint => W::Rgba8Sint,
486 TextureFormat::Bgra8Unorm => W::Bgra8Unorm,
487 TextureFormat::Bgra8UnormSrgb => W::Bgra8UnormSrgb,
488 TextureFormat::Rgb10A2Uint => W::Rgb10a2Uint,
489 TextureFormat::Rgb10A2Unorm => W::Rgb10a2Unorm,
490 TextureFormat::Rg11B10Ufloat => W::Rg11b10Ufloat,
491 TextureFormat::Rgb9E5Ufloat => W::Rgb9e5Ufloat,
492 TextureFormat::Rg32Float => W::Rg32Float,
493 TextureFormat::Rg32Uint => W::Rg32Uint,
494 TextureFormat::Rg32Sint => W::Rg32Sint,
495 TextureFormat::Rgba16Unorm => W::Rgba16Unorm,
496 TextureFormat::Rgba16Snorm => W::Rgba16Snorm,
497 TextureFormat::Rgba16Uint => W::Rgba16Uint,
498 TextureFormat::Rgba16Sint => W::Rgba16Sint,
499 TextureFormat::Rgba16Float => W::Rgba16Float,
500 TextureFormat::Rgba32Float => W::Rgba32Float,
501 TextureFormat::Rgba32Uint => W::Rgba32Uint,
502 TextureFormat::Rgba32Sint => W::Rgba32Sint,
503 TextureFormat::Stencil8 => W::Stencil8,
504 TextureFormat::Depth16Unorm => W::Depth16Unorm,
505 TextureFormat::Depth24Plus => W::Depth24Plus,
506 TextureFormat::Depth24PlusStencil8 => W::Depth24PlusStencil8,
507 TextureFormat::Depth32Float => W::Depth32Float,
508 TextureFormat::Depth32FloatStencil8 => W::Depth32FloatStencil8,
509 TextureFormat::Bc1RgbaUnorm => W::Bc1RgbaUnorm,
510 TextureFormat::Bc1RgbaUnormSrgb => W::Bc1RgbaUnormSrgb,
511 TextureFormat::Bc2RgbaUnorm => W::Bc2RgbaUnorm,
512 TextureFormat::Bc2RgbaUnormSrgb => W::Bc2RgbaUnormSrgb,
513 TextureFormat::Bc3RgbaUnorm => W::Bc3RgbaUnorm,
514 TextureFormat::Bc3RgbaUnormSrgb => W::Bc3RgbaUnormSrgb,
515 TextureFormat::Bc4RUnorm => W::Bc4RUnorm,
516 TextureFormat::Bc4RSnorm => W::Bc4RSnorm,
517 TextureFormat::Bc5RgUnorm => W::Bc5RgUnorm,
518 TextureFormat::Bc5RgSnorm => W::Bc5RgSnorm,
519 TextureFormat::Bc6HRgbUfloat => W::Bc6hRgbUfloat,
520 TextureFormat::Bc6HRgbFloat => W::Bc6hRgbFloat,
521 TextureFormat::Bc7RgbaUnorm => W::Bc7RgbaUnorm,
522 TextureFormat::Bc7RgbaUnormSrgb => W::Bc7RgbaUnormSrgb,
523 TextureFormat::Etc2Rgb8Unorm => W::Etc2Rgb8Unorm,
524 TextureFormat::Etc2Rgb8UnormSrgb => W::Etc2Rgb8UnormSrgb,
525 TextureFormat::Etc2Rgb8A1Unorm => W::Etc2Rgb8A1Unorm,
526 TextureFormat::Etc2Rgb8A1UnormSrgb => W::Etc2Rgb8A1UnormSrgb,
527 TextureFormat::Etc2Rgba8Unorm => W::Etc2Rgba8Unorm,
528 TextureFormat::Etc2Rgba8UnormSrgb => W::Etc2Rgba8UnormSrgb,
529 TextureFormat::EacR11Unorm => W::EacR11Unorm,
530 TextureFormat::EacR11Snorm => W::EacR11Snorm,
531 TextureFormat::EacRg11Unorm => W::EacRg11Unorm,
532 TextureFormat::EacRg11Snorm => W::EacRg11Snorm,
533 TextureFormat::Astc4X4Unorm => W::Astc {
534 block: wgpu::AstcBlock::B4x4,
535 channel: wgpu::AstcChannel::Unorm,
536 },
537 TextureFormat::Astc4X4UnormSrgb => W::Astc {
538 block: wgpu::AstcBlock::B4x4,
539 channel: wgpu::AstcChannel::UnormSrgb,
540 },
541 TextureFormat::Astc5X4Unorm => W::Astc {
542 block: wgpu::AstcBlock::B5x4,
543 channel: wgpu::AstcChannel::Unorm,
544 },
545 TextureFormat::Astc5X4UnormSrgb => W::Astc {
546 block: wgpu::AstcBlock::B5x4,
547 channel: wgpu::AstcChannel::UnormSrgb,
548 },
549 TextureFormat::Astc5X5Unorm => W::Astc {
550 block: wgpu::AstcBlock::B5x5,
551 channel: wgpu::AstcChannel::Unorm,
552 },
553 TextureFormat::Astc5X5UnormSrgb => W::Astc {
554 block: wgpu::AstcBlock::B5x5,
555 channel: wgpu::AstcChannel::UnormSrgb,
556 },
557 TextureFormat::Astc6X5Unorm => W::Astc {
558 block: wgpu::AstcBlock::B6x5,
559 channel: wgpu::AstcChannel::Unorm,
560 },
561 TextureFormat::Astc6X5UnormSrgb => W::Astc {
562 block: wgpu::AstcBlock::B6x5,
563 channel: wgpu::AstcChannel::UnormSrgb,
564 },
565 TextureFormat::Astc6X6Unorm => W::Astc {
566 block: wgpu::AstcBlock::B6x6,
567 channel: wgpu::AstcChannel::Unorm,
568 },
569 TextureFormat::Astc6X6UnormSrgb => W::Astc {
570 block: wgpu::AstcBlock::B6x6,
571 channel: wgpu::AstcChannel::UnormSrgb,
572 },
573 TextureFormat::Astc8X5Unorm => W::Astc {
574 block: wgpu::AstcBlock::B8x5,
575 channel: wgpu::AstcChannel::Unorm,
576 },
577 TextureFormat::Astc8X5UnormSrgb => W::Astc {
578 block: wgpu::AstcBlock::B8x5,
579 channel: wgpu::AstcChannel::UnormSrgb,
580 },
581 TextureFormat::Astc8X6Unorm => W::Astc {
582 block: wgpu::AstcBlock::B8x6,
583 channel: wgpu::AstcChannel::Unorm,
584 },
585 TextureFormat::Astc8X6UnormSrgb => W::Astc {
586 block: wgpu::AstcBlock::B8x6,
587 channel: wgpu::AstcChannel::UnormSrgb,
588 },
589 TextureFormat::Astc8X8Unorm => W::Astc {
590 block: wgpu::AstcBlock::B8x8,
591 channel: wgpu::AstcChannel::Unorm,
592 },
593 TextureFormat::Astc8X8UnormSrgb => W::Astc {
594 block: wgpu::AstcBlock::B8x8,
595 channel: wgpu::AstcChannel::UnormSrgb,
596 },
597 TextureFormat::Astc10X5Unorm => W::Astc {
598 block: wgpu::AstcBlock::B10x5,
599 channel: wgpu::AstcChannel::Unorm,
600 },
601 TextureFormat::Astc10X5UnormSrgb => W::Astc {
602 block: wgpu::AstcBlock::B10x5,
603 channel: wgpu::AstcChannel::UnormSrgb,
604 },
605 TextureFormat::Astc10X6Unorm => W::Astc {
606 block: wgpu::AstcBlock::B10x6,
607 channel: wgpu::AstcChannel::Unorm,
608 },
609 TextureFormat::Astc10X6UnormSrgb => W::Astc {
610 block: wgpu::AstcBlock::B10x6,
611 channel: wgpu::AstcChannel::UnormSrgb,
612 },
613 TextureFormat::Astc10X8Unorm => W::Astc {
614 block: wgpu::AstcBlock::B10x8,
615 channel: wgpu::AstcChannel::Unorm,
616 },
617 TextureFormat::Astc10X8UnormSrgb => W::Astc {
618 block: wgpu::AstcBlock::B10x8,
619 channel: wgpu::AstcChannel::UnormSrgb,
620 },
621 TextureFormat::Astc10X10Unorm => W::Astc {
622 block: wgpu::AstcBlock::B10x10,
623 channel: wgpu::AstcChannel::Unorm,
624 },
625 TextureFormat::Astc10X10UnormSrgb => W::Astc {
626 block: wgpu::AstcBlock::B10x10,
627 channel: wgpu::AstcChannel::UnormSrgb,
628 },
629 TextureFormat::Astc12X10Unorm => W::Astc {
630 block: wgpu::AstcBlock::B12x10,
631 channel: wgpu::AstcChannel::Unorm,
632 },
633 TextureFormat::Astc12X10UnormSrgb => W::Astc {
634 block: wgpu::AstcBlock::B12x10,
635 channel: wgpu::AstcChannel::UnormSrgb,
636 },
637 TextureFormat::Astc12X12Unorm => W::Astc {
638 block: wgpu::AstcBlock::B12x12,
639 channel: wgpu::AstcChannel::Unorm,
640 },
641 TextureFormat::Astc12X12UnormSrgb => W::Astc {
642 block: wgpu::AstcBlock::B12x12,
643 channel: wgpu::AstcChannel::UnormSrgb,
644 },
645 _ => panic!("wgpu-compat: unsupported texture format conversion"),
646 }
647}
648
649fn map_texture_dimension(value: wgpu::TextureDimension) -> TextureDimension {
650 match value {
651 wgpu::TextureDimension::D1 => TextureDimension::D1,
652 wgpu::TextureDimension::D2 => TextureDimension::D2,
653 wgpu::TextureDimension::D3 => TextureDimension::D3,
654 _ => TextureDimension::D2,
655 }
656}
657
658fn map_texture_view_dimension(value: wgpu::TextureViewDimension) -> TextureViewDimension {
659 match value {
660 wgpu::TextureViewDimension::D1 => TextureViewDimension::D1,
661 wgpu::TextureViewDimension::D2 => TextureViewDimension::D2,
662 wgpu::TextureViewDimension::D2Array => TextureViewDimension::D2Array,
663 wgpu::TextureViewDimension::Cube => TextureViewDimension::Cube,
664 wgpu::TextureViewDimension::CubeArray => TextureViewDimension::CubeArray,
665 wgpu::TextureViewDimension::D3 => TextureViewDimension::D3,
666 _ => TextureViewDimension::D2,
667 }
668}
669
670fn map_texture_aspect(value: wgpu::TextureAspect) -> TextureAspect {
671 match value {
672 wgpu::TextureAspect::All => TextureAspect::All,
673 wgpu::TextureAspect::StencilOnly => TextureAspect::StencilOnly,
674 wgpu::TextureAspect::DepthOnly => TextureAspect::DepthOnly,
675 wgpu::TextureAspect::Plane0 => TextureAspect::Plane0Only,
676 wgpu::TextureAspect::Plane1 => TextureAspect::Plane1Only,
677 wgpu::TextureAspect::Plane2 => TextureAspect::Plane2Only,
678 _ => TextureAspect::All,
679 }
680}
681
682fn map_filter_mode(value: wgpu::FilterMode) -> FilterMode {
683 match value {
684 wgpu::FilterMode::Nearest => FilterMode::Nearest,
685 wgpu::FilterMode::Linear => FilterMode::Linear,
686 _ => FilterMode::Nearest,
687 }
688}
689
690fn map_mipmap_filter_mode(value: wgpu::MipmapFilterMode) -> MipmapFilterMode {
691 match value {
692 wgpu::MipmapFilterMode::Nearest => MipmapFilterMode::Nearest,
693 wgpu::MipmapFilterMode::Linear => MipmapFilterMode::Linear,
694 _ => MipmapFilterMode::Nearest,
695 }
696}
697
698fn map_address_mode(value: wgpu::AddressMode) -> AddressMode {
699 match value {
700 wgpu::AddressMode::ClampToEdge => AddressMode::ClampToEdge,
701 wgpu::AddressMode::Repeat => AddressMode::Repeat,
702 wgpu::AddressMode::MirrorRepeat => AddressMode::MirrorRepeat,
703 _ => AddressMode::ClampToEdge,
704 }
705}
706
707fn map_compare_function(value: wgpu::CompareFunction) -> CompareFunction {
708 match value {
709 wgpu::CompareFunction::Never => CompareFunction::Never,
710 wgpu::CompareFunction::Less => CompareFunction::Less,
711 wgpu::CompareFunction::Equal => CompareFunction::Equal,
712 wgpu::CompareFunction::LessEqual => CompareFunction::LessEqual,
713 wgpu::CompareFunction::Greater => CompareFunction::Greater,
714 wgpu::CompareFunction::NotEqual => CompareFunction::NotEqual,
715 wgpu::CompareFunction::GreaterEqual => CompareFunction::GreaterEqual,
716 wgpu::CompareFunction::Always => CompareFunction::Always,
717 _ => CompareFunction::Always,
718 }
719}
720
721fn map_index_format(value: wgpu::IndexFormat) -> IndexFormat {
722 match value {
723 wgpu::IndexFormat::Uint16 => IndexFormat::Uint16,
724 wgpu::IndexFormat::Uint32 => IndexFormat::Uint32,
725 _ => IndexFormat::Uint32,
726 }
727}
728
729fn map_primitive_topology(value: wgpu::PrimitiveTopology) -> PrimitiveTopology {
730 match value {
731 wgpu::PrimitiveTopology::PointList => PrimitiveTopology::PointList,
732 wgpu::PrimitiveTopology::LineList => PrimitiveTopology::LineList,
733 wgpu::PrimitiveTopology::LineStrip => PrimitiveTopology::LineStrip,
734 wgpu::PrimitiveTopology::TriangleList => PrimitiveTopology::TriangleList,
735 wgpu::PrimitiveTopology::TriangleStrip => PrimitiveTopology::TriangleStrip,
736 _ => PrimitiveTopology::TriangleList,
737 }
738}
739
740fn map_front_face(value: wgpu::FrontFace) -> FrontFace {
741 match value {
742 wgpu::FrontFace::Ccw => FrontFace::Ccw,
743 wgpu::FrontFace::Cw => FrontFace::Cw,
744 _ => FrontFace::Ccw,
745 }
746}
747
748fn map_cull_mode(value: Option<wgpu::Face>) -> CullMode {
749 match value {
750 Some(wgpu::Face::Front) => CullMode::Front,
751 Some(wgpu::Face::Back) => CullMode::Back,
752 None => CullMode::None,
753 }
754}
755
756fn map_stencil_operation(value: wgpu::StencilOperation) -> StencilOperation {
757 match value {
758 wgpu::StencilOperation::Keep => StencilOperation::Keep,
759 wgpu::StencilOperation::Zero => StencilOperation::Zero,
760 wgpu::StencilOperation::Replace => StencilOperation::Replace,
761 wgpu::StencilOperation::Invert => StencilOperation::Invert,
762 wgpu::StencilOperation::IncrementClamp => StencilOperation::IncrementClamp,
763 wgpu::StencilOperation::DecrementClamp => StencilOperation::DecrementClamp,
764 wgpu::StencilOperation::IncrementWrap => StencilOperation::IncrementWrap,
765 wgpu::StencilOperation::DecrementWrap => StencilOperation::DecrementWrap,
766 _ => StencilOperation::Keep,
767 }
768}
769
770fn map_blend_operation(value: wgpu::BlendOperation) -> BlendOperation {
771 match value {
772 wgpu::BlendOperation::Add => BlendOperation::Add,
773 wgpu::BlendOperation::Subtract => BlendOperation::Subtract,
774 wgpu::BlendOperation::ReverseSubtract => BlendOperation::ReverseSubtract,
775 wgpu::BlendOperation::Min => BlendOperation::Min,
776 wgpu::BlendOperation::Max => BlendOperation::Max,
777 _ => BlendOperation::Add,
778 }
779}
780
781fn map_blend_factor(value: wgpu::BlendFactor) -> BlendFactor {
782 match value {
783 wgpu::BlendFactor::Zero => BlendFactor::Zero,
784 wgpu::BlendFactor::One => BlendFactor::One,
785 wgpu::BlendFactor::Src => BlendFactor::Src,
786 wgpu::BlendFactor::OneMinusSrc => BlendFactor::OneMinusSrc,
787 wgpu::BlendFactor::SrcAlpha => BlendFactor::SrcAlpha,
788 wgpu::BlendFactor::OneMinusSrcAlpha => BlendFactor::OneMinusSrcAlpha,
789 wgpu::BlendFactor::Dst => BlendFactor::Dst,
790 wgpu::BlendFactor::OneMinusDst => BlendFactor::OneMinusDst,
791 wgpu::BlendFactor::DstAlpha => BlendFactor::DstAlpha,
792 wgpu::BlendFactor::OneMinusDstAlpha => BlendFactor::OneMinusDstAlpha,
793 wgpu::BlendFactor::SrcAlphaSaturated => BlendFactor::SrcAlphaSaturated,
794 wgpu::BlendFactor::Constant => BlendFactor::Constant,
795 wgpu::BlendFactor::OneMinusConstant => BlendFactor::OneMinusConstant,
796 _ => BlendFactor::One,
797 }
798}
799
800fn map_color_write_mask(value: wgpu::ColorWrites) -> ColorWriteMask {
801 ColorWriteMask::from_bits_truncate(value.bits() as u64)
802}
803
804fn map_buffer_usages(value: wgpu::BufferUsages) -> BufferUsage {
805 BufferUsage::from_bits_truncate(value.bits() as u64)
806}
807
808fn map_texture_usages(value: wgpu::TextureUsages) -> TextureUsage {
809 TextureUsage::from_bits_truncate(value.bits() as u64)
810}
811
812fn map_texture_usage_to_wgpu(value: TextureUsage) -> wgpu::TextureUsages {
813 let mut out = wgpu::TextureUsages::empty();
814 if value.contains(TextureUsage::COPY_SRC) {
815 out |= wgpu::TextureUsages::COPY_SRC;
816 }
817 if value.contains(TextureUsage::COPY_DST) {
818 out |= wgpu::TextureUsages::COPY_DST;
819 }
820 if value.contains(TextureUsage::TEXTURE_BINDING) {
821 out |= wgpu::TextureUsages::TEXTURE_BINDING;
822 }
823 if value.contains(TextureUsage::STORAGE_BINDING) {
824 out |= wgpu::TextureUsages::STORAGE_BINDING;
825 }
826 if value.contains(TextureUsage::RENDER_ATTACHMENT) {
827 out |= wgpu::TextureUsages::RENDER_ATTACHMENT;
828 }
829 if value.contains(TextureUsage::TRANSIENT_ATTACHMENT) {
830 out |= wgpu::TextureUsages::TRANSIENT;
831 }
832 if value.contains(TextureUsage::STORAGE_ATTACHMENT) {
833 out |= wgpu::TextureUsages::STORAGE_BINDING;
834 }
835 out
836}
837
838fn map_shader_stages(value: wgpu::ShaderStages) -> ShaderStage {
839 ShaderStage::from_bits_truncate(value.bits() as u64)
840}
841
842fn map_sampler_binding_type(value: wgpu::SamplerBindingType) -> SamplerBindingType {
843 match value {
844 wgpu::SamplerBindingType::Filtering => SamplerBindingType::Filtering,
845 wgpu::SamplerBindingType::NonFiltering => SamplerBindingType::NonFiltering,
846 wgpu::SamplerBindingType::Comparison => SamplerBindingType::Comparison,
847 _ => SamplerBindingType::Filtering,
848 }
849}
850
851fn map_texture_sample_type(value: wgpu::TextureSampleType) -> TextureSampleType {
852 match value {
853 wgpu::TextureSampleType::Float { filterable } => {
854 if filterable {
855 TextureSampleType::Float
856 } else {
857 TextureSampleType::UnfilterableFloat
858 }
859 }
860 wgpu::TextureSampleType::Depth => TextureSampleType::Depth,
861 wgpu::TextureSampleType::Sint => TextureSampleType::Sint,
862 wgpu::TextureSampleType::Uint => TextureSampleType::Uint,
863 _ => TextureSampleType::Float,
864 }
865}
866
867fn map_storage_texture_access(value: wgpu::StorageTextureAccess) -> StorageTextureAccess {
868 match value {
869 wgpu::StorageTextureAccess::ReadOnly => StorageTextureAccess::ReadOnly,
870 wgpu::StorageTextureAccess::WriteOnly => StorageTextureAccess::WriteOnly,
871 wgpu::StorageTextureAccess::ReadWrite => StorageTextureAccess::ReadWrite,
872 _ => StorageTextureAccess::WriteOnly,
873 }
874}
875
876fn map_vertex_format(value: wgpu::VertexFormat) -> VertexFormat {
877 match value {
878 wgpu::VertexFormat::Uint8x2 => VertexFormat::Uint8X2,
879 wgpu::VertexFormat::Uint8x4 => VertexFormat::Uint8X4,
880 wgpu::VertexFormat::Sint8x2 => VertexFormat::Sint8X2,
881 wgpu::VertexFormat::Sint8x4 => VertexFormat::Sint8X4,
882 wgpu::VertexFormat::Unorm8x2 => VertexFormat::Unorm8X2,
883 wgpu::VertexFormat::Unorm8x4 => VertexFormat::Unorm8X4,
884 wgpu::VertexFormat::Snorm8x2 => VertexFormat::Snorm8X2,
885 wgpu::VertexFormat::Snorm8x4 => VertexFormat::Snorm8X4,
886 wgpu::VertexFormat::Uint16x2 => VertexFormat::Uint16X2,
887 wgpu::VertexFormat::Uint16x4 => VertexFormat::Uint16X4,
888 wgpu::VertexFormat::Sint16x2 => VertexFormat::Sint16X2,
889 wgpu::VertexFormat::Sint16x4 => VertexFormat::Sint16X4,
890 wgpu::VertexFormat::Unorm16x2 => VertexFormat::Unorm16X2,
891 wgpu::VertexFormat::Unorm16x4 => VertexFormat::Unorm16X4,
892 wgpu::VertexFormat::Snorm16x2 => VertexFormat::Snorm16X2,
893 wgpu::VertexFormat::Snorm16x4 => VertexFormat::Snorm16X4,
894 wgpu::VertexFormat::Float16x2 => VertexFormat::Float16X2,
895 wgpu::VertexFormat::Float16x4 => VertexFormat::Float16X4,
896 wgpu::VertexFormat::Float32 => VertexFormat::Float32,
897 wgpu::VertexFormat::Float32x2 => VertexFormat::Float32X2,
898 wgpu::VertexFormat::Float32x3 => VertexFormat::Float32X3,
899 wgpu::VertexFormat::Float32x4 => VertexFormat::Float32X4,
900 wgpu::VertexFormat::Uint32 => VertexFormat::Uint32,
901 wgpu::VertexFormat::Uint32x2 => VertexFormat::Uint32X2,
902 wgpu::VertexFormat::Uint32x3 => VertexFormat::Uint32X3,
903 wgpu::VertexFormat::Uint32x4 => VertexFormat::Uint32X4,
904 wgpu::VertexFormat::Sint32 => VertexFormat::Sint32,
905 wgpu::VertexFormat::Sint32x2 => VertexFormat::Sint32X2,
906 wgpu::VertexFormat::Sint32x3 => VertexFormat::Sint32X3,
907 wgpu::VertexFormat::Sint32x4 => VertexFormat::Sint32X4,
908 wgpu::VertexFormat::Unorm10_10_10_2 => VertexFormat::Unorm1010102,
909 wgpu::VertexFormat::Unorm8x4Bgra => VertexFormat::Unorm8X4Bgra,
910 _ => VertexFormat::Float32X3,
911 }
912}
913
914fn map_vertex_step_mode(value: wgpu::VertexStepMode) -> VertexStepMode {
915 match value {
916 wgpu::VertexStepMode::Vertex => VertexStepMode::Vertex,
917 wgpu::VertexStepMode::Instance => VertexStepMode::Instance,
918 _ => VertexStepMode::Vertex,
919 }
920}
921
922fn map_load_op<T>(value: wgpu::LoadOp<T>) -> LoadOp {
923 match value {
924 wgpu::LoadOp::Load => LoadOp::Load,
925 wgpu::LoadOp::Clear(_) => LoadOp::Clear,
926 wgpu::LoadOp::DontCare(_) => LoadOp::Load,
927 }
928}
929
930fn map_store_op(value: wgpu::StoreOp) -> StoreOp {
931 match value {
932 wgpu::StoreOp::Store => StoreOp::Store,
933 wgpu::StoreOp::Discard => StoreOp::Discard,
934 _ => StoreOp::Store,
935 }
936}
937
938fn map_color(value: wgpu::Color) -> Color {
939 Color {
940 r: Some(value.r),
941 g: Some(value.g),
942 b: Some(value.b),
943 a: Some(value.a),
944 }
945}
946
947fn map_origin_3d(value: wgpu::Origin3d) -> Origin3D {
948 Origin3D {
949 x: Some(value.x),
950 y: Some(value.y),
951 z: Some(value.z),
952 }
953}
954
955fn map_extent_3d(value: wgpu::Extent3d) -> Extent3D {
956 Extent3D {
957 width: Some(value.width),
958 height: Some(value.height),
959 depth_or_array_layers: Some(value.depth_or_array_layers),
960 }
961}
962
963fn map_texel_copy_buffer_layout(value: wgpu::TexelCopyBufferLayout) -> TexelCopyBufferLayout {
964 TexelCopyBufferLayout {
965 offset: Some(value.offset),
966 bytes_per_row: value.bytes_per_row,
967 rows_per_image: value.rows_per_image,
968 }
969}
970
971fn map_texel_copy_buffer_info(value: wgpu::TexelCopyBufferInfo<'_>) -> TexelCopyBufferInfo {
972 TexelCopyBufferInfo {
973 layout: Some(map_texel_copy_buffer_layout(value.layout)),
974 buffer: Some(expect_buffer_from_api(value.buffer)),
975 }
976}
977
978fn map_texel_copy_texture_info(value: wgpu::TexelCopyTextureInfo<'_>) -> TexelCopyTextureInfo {
979 TexelCopyTextureInfo {
980 texture: Some(expect_texture_from_api(value.texture)),
981 mip_level: Some(value.mip_level),
982 origin: Some(map_origin_3d(value.origin)),
983 aspect: Some(map_texture_aspect(value.aspect)),
984 }
985}
986
987fn map_shader_module_descriptor(desc: wgpu::ShaderModuleDescriptor<'_>) -> ShaderModuleDescriptor {
988 let mut out = ShaderModuleDescriptor::new();
989 out.label = label_to_string(desc.label);
990 match desc.source {
991 wgpu::ShaderSource::Wgsl(source) => {
992 let ext = ShaderSourceWGSL {
993 code: Some(source.to_string()),
994 };
995 out = out.with_extension(ShaderModuleDescriptorExtension::from(ext));
996 }
997 _ => panic!("wgpu-compat: unsupported shader source"),
998 }
999 out
1000}
1001
1002fn map_buffer_descriptor(desc: &wgpu::BufferDescriptor<'_>) -> BufferDescriptor {
1003 let mut out = BufferDescriptor::new();
1004 out.label = label_to_string(desc.label);
1005 out.size = Some(desc.size);
1006 out.usage = Some(map_buffer_usages(desc.usage));
1007 out.mapped_at_creation = Some(desc.mapped_at_creation);
1008 out
1009}
1010
1011fn map_texture_descriptor(desc: &wgpu::TextureDescriptor<'_>) -> TextureDescriptor {
1012 let mut out = TextureDescriptor::new();
1013 out.label = label_to_string(desc.label);
1014 out.size = Some(map_extent_3d(desc.size));
1015 out.mip_level_count = Some(desc.mip_level_count);
1016 out.sample_count = Some(desc.sample_count);
1017 out.dimension = Some(map_texture_dimension(desc.dimension));
1018 out.format = Some(map_texture_format(desc.format));
1019 out.usage = Some(map_texture_usages(desc.usage));
1020 out.view_formats = Some(
1021 desc.view_formats
1022 .iter()
1023 .copied()
1024 .map(map_texture_format)
1025 .collect(),
1026 );
1027 out
1028}
1029
1030fn map_texture_view_descriptor(desc: &wgpu::TextureViewDescriptor<'_>) -> TextureViewDescriptor {
1031 let mut out = TextureViewDescriptor::new();
1032 out.label = label_to_string(desc.label);
1033 out.format = desc.format.map(map_texture_format);
1034 out.dimension = desc.dimension.map(map_texture_view_dimension);
1035 out.aspect = Some(map_texture_aspect(desc.aspect));
1036 out.base_mip_level = Some(desc.base_mip_level);
1037 if let Some(count) = desc.mip_level_count {
1038 out.mip_level_count = Some(count);
1039 }
1040 out.base_array_layer = Some(desc.base_array_layer);
1041 if let Some(count) = desc.array_layer_count {
1042 out.array_layer_count = Some(count);
1043 }
1044 out.usage = desc.usage.map(map_texture_usages);
1045 out
1046}
1047
1048fn map_sampler_descriptor(desc: &wgpu::SamplerDescriptor<'_>) -> SamplerDescriptor {
1049 let mut out = SamplerDescriptor::new();
1050 out.label = label_to_string(desc.label);
1051 out.address_mode_u = Some(map_address_mode(desc.address_mode_u));
1052 out.address_mode_v = Some(map_address_mode(desc.address_mode_v));
1053 out.address_mode_w = Some(map_address_mode(desc.address_mode_w));
1054 out.mag_filter = Some(map_filter_mode(desc.mag_filter));
1055 out.min_filter = Some(map_filter_mode(desc.min_filter));
1056 out.mipmap_filter = Some(map_mipmap_filter_mode(desc.mipmap_filter));
1057 out.lod_min_clamp = Some(desc.lod_min_clamp);
1058 out.lod_max_clamp = Some(desc.lod_max_clamp);
1059 out.compare = desc.compare.map(map_compare_function);
1060 out.max_anisotropy = Some(desc.anisotropy_clamp);
1061 out
1062}
1063
1064fn map_bind_group_layout_entry(entry: &wgpu::BindGroupLayoutEntry) -> BindGroupLayoutEntry {
1065 let mut out = BindGroupLayoutEntry::new();
1066 out.binding = Some(entry.binding);
1067 out.visibility = Some(map_shader_stages(entry.visibility));
1068 out.binding_array_size = entry.count.map(|v| v.get()).or(Some(0));
1069
1070 match entry.ty {
1071 wgpu::BindingType::Buffer {
1072 ty,
1073 has_dynamic_offset,
1074 min_binding_size,
1075 } => {
1076 let mut layout = BufferBindingLayout::new();
1077 layout.r#type = Some(match ty {
1078 wgpu::BufferBindingType::Uniform => BufferBindingType::Uniform,
1079 wgpu::BufferBindingType::Storage { read_only } => {
1080 if read_only {
1081 BufferBindingType::ReadOnlyStorage
1082 } else {
1083 BufferBindingType::Storage
1084 }
1085 }
1086 _ => BufferBindingType::Uniform,
1087 });
1088 layout.has_dynamic_offset = Some(has_dynamic_offset);
1089 layout.min_binding_size = min_binding_size.map(|v| v.get());
1090 out.buffer = Some(layout);
1091 }
1092 wgpu::BindingType::Sampler(ty) => {
1093 let mut layout = SamplerBindingLayout::new();
1094 layout.r#type = Some(map_sampler_binding_type(ty));
1095 out.sampler = Some(layout);
1096 }
1097 wgpu::BindingType::Texture {
1098 sample_type,
1099 view_dimension,
1100 multisampled,
1101 } => {
1102 let mut layout = TextureBindingLayout::new();
1103 layout.sample_type = Some(map_texture_sample_type(sample_type));
1104 layout.view_dimension = Some(map_texture_view_dimension(view_dimension));
1105 layout.multisampled = Some(multisampled);
1106 out.texture = Some(layout);
1107 }
1108 wgpu::BindingType::StorageTexture {
1109 access,
1110 format,
1111 view_dimension,
1112 } => {
1113 let mut layout = StorageTextureBindingLayout::new();
1114 layout.access = Some(map_storage_texture_access(access));
1115 layout.format = Some(map_texture_format(format));
1116 layout.view_dimension = Some(map_texture_view_dimension(view_dimension));
1117 out.storage_texture = Some(layout);
1118 }
1119 _ => panic!("wgpu-compat: unsupported binding type"),
1120 }
1121
1122 out
1123}
1124
1125fn map_bind_group_layout_descriptor(
1126 desc: &wgpu::BindGroupLayoutDescriptor<'_>,
1127) -> BindGroupLayoutDescriptor {
1128 let mut out = BindGroupLayoutDescriptor::new();
1129 out.label = label_to_string(desc.label);
1130 out.entries = Some(
1131 desc.entries
1132 .iter()
1133 .map(map_bind_group_layout_entry)
1134 .collect(),
1135 );
1136 out
1137}
1138
1139fn map_bind_group_entry(entry: &wgpu::BindGroupEntry<'_>) -> BindGroupEntry {
1140 let mut out = BindGroupEntry::default();
1141 out.binding = Some(entry.binding);
1142 match &entry.resource {
1143 wgpu::BindingResource::Buffer(buffer) => {
1144 out.buffer = Some(expect_buffer_from_api(buffer.buffer));
1145 out.offset = Some(buffer.offset);
1146 out.size = Some(buffer.size.map(|v| v.get()).unwrap_or(WHOLE_SIZE));
1147 }
1148 wgpu::BindingResource::Sampler(sampler) => {
1149 out.sampler = Some(expect_sampler_from_api(sampler));
1150 }
1151 wgpu::BindingResource::TextureView(view) => {
1152 out.texture_view = Some(expect_texture_view_from_api(view));
1153 }
1154 _ => panic!("wgpu-compat: binding resource arrays not supported"),
1155 }
1156 out
1157}
1158
1159fn map_bind_group_descriptor(desc: &wgpu::BindGroupDescriptor<'_>) -> BindGroupDescriptor {
1160 let mut out = BindGroupDescriptor::new();
1161 out.label = label_to_string(desc.label);
1162 out.layout = Some(expect_bind_group_layout_from_api(desc.layout));
1163 out.entries = Some(desc.entries.iter().map(map_bind_group_entry).collect());
1164 out
1165}
1166
1167fn map_pipeline_layout_descriptor(
1168 desc: &wgpu::PipelineLayoutDescriptor<'_>,
1169) -> PipelineLayoutDescriptor {
1170 let mut out = PipelineLayoutDescriptor::new();
1171 out.label = label_to_string(desc.label);
1172 out.bind_group_layouts = Some(
1173 desc.bind_group_layouts
1174 .iter()
1175 .copied()
1176 .map(expect_bind_group_layout_from_api)
1177 .collect(),
1178 );
1179 out.immediate_size = Some(0);
1180 out
1181}
1182
1183fn map_vertex_attribute(attr: &wgpu::VertexAttribute) -> VertexAttribute {
1184 let mut out = VertexAttribute::new();
1185 out.format = Some(map_vertex_format(attr.format));
1186 out.offset = Some(attr.offset);
1187 out.shader_location = Some(attr.shader_location);
1188 out
1189}
1190
1191fn map_vertex_buffer_layout(layout: &wgpu::VertexBufferLayout<'_>) -> VertexBufferLayout {
1192 let mut out = VertexBufferLayout::new();
1193 out.array_stride = Some(layout.array_stride);
1194 out.step_mode = Some(map_vertex_step_mode(layout.step_mode));
1195 out.attributes = Some(layout.attributes.iter().map(map_vertex_attribute).collect());
1196 out
1197}
1198
1199fn map_vertex_state(state: &wgpu::VertexState<'_>) -> VertexState {
1200 let mut out = VertexState::new();
1201 out.module = Some(expect_shader_module_from_api(state.module));
1202 out.entry_point = state.entry_point.map(str::to_string);
1203 out.constants = Some(
1204 state
1205 .compilation_options
1206 .constants
1207 .iter()
1208 .map(|(k, v)| {
1209 let mut entry = ConstantEntry::new();
1210 entry.key = Some(k.to_string());
1211 entry.value = Some(*v);
1212 entry
1213 })
1214 .collect(),
1215 );
1216 out.buffers = Some(state.buffers.iter().map(map_vertex_buffer_layout).collect());
1217 out
1218}
1219
1220fn map_blend_component(comp: &wgpu::BlendComponent) -> BlendComponent {
1221 BlendComponent {
1222 operation: Some(map_blend_operation(comp.operation)),
1223 src_factor: Some(map_blend_factor(comp.src_factor)),
1224 dst_factor: Some(map_blend_factor(comp.dst_factor)),
1225 }
1226}
1227
1228fn map_blend_state(state: &wgpu::BlendState) -> BlendState {
1229 BlendState {
1230 color: Some(map_blend_component(&state.color)),
1231 alpha: Some(map_blend_component(&state.alpha)),
1232 }
1233}
1234
1235fn map_color_target_state(state: &wgpu::ColorTargetState) -> ColorTargetState {
1236 let mut out = ColorTargetState::new();
1237 out.format = Some(map_texture_format(state.format));
1238 out.blend = state.blend.as_ref().map(map_blend_state);
1239 out.write_mask = Some(map_color_write_mask(state.write_mask));
1240 out
1241}
1242
1243fn map_fragment_state(state: &wgpu::FragmentState<'_>) -> FragmentState {
1244 let mut out = FragmentState::new();
1245 out.module = Some(expect_shader_module_from_api(state.module));
1246 out.entry_point = state.entry_point.map(str::to_string);
1247 out.constants = Some(
1248 state
1249 .compilation_options
1250 .constants
1251 .iter()
1252 .map(|(k, v)| {
1253 let mut entry = ConstantEntry::new();
1254 entry.key = Some(k.to_string());
1255 entry.value = Some(*v);
1256 entry
1257 })
1258 .collect(),
1259 );
1260 out.targets = Some(
1261 state
1262 .targets
1263 .iter()
1264 .map(|t| t.as_ref().map(map_color_target_state).unwrap_or_default())
1265 .collect(),
1266 );
1267 out
1268}
1269
1270fn map_stencil_face_state(state: &wgpu::StencilFaceState) -> StencilFaceState {
1271 StencilFaceState {
1272 compare: Some(map_compare_function(state.compare)),
1273 fail_op: Some(map_stencil_operation(state.fail_op)),
1274 depth_fail_op: Some(map_stencil_operation(state.depth_fail_op)),
1275 pass_op: Some(map_stencil_operation(state.pass_op)),
1276 }
1277}
1278
1279fn map_depth_stencil_state(state: &wgpu::DepthStencilState) -> DepthStencilState {
1280 let mut out = DepthStencilState::new();
1281 out.format = Some(map_texture_format(state.format));
1282 out.depth_write_enabled = Some(if state.depth_write_enabled {
1283 OptionalBool::True
1284 } else {
1285 OptionalBool::False
1286 });
1287 out.depth_compare = Some(map_compare_function(state.depth_compare));
1288 out.stencil_front = Some(map_stencil_face_state(&state.stencil.front));
1289 out.stencil_back = Some(map_stencil_face_state(&state.stencil.back));
1290 out.stencil_read_mask = Some(state.stencil.read_mask);
1291 out.stencil_write_mask = Some(state.stencil.write_mask);
1292 out.depth_bias = Some(state.bias.constant);
1293 out.depth_bias_slope_scale = Some(state.bias.slope_scale);
1294 out.depth_bias_clamp = Some(state.bias.clamp);
1295 out
1296}
1297
1298fn map_multisample_state(state: wgpu::MultisampleState) -> MultisampleState {
1299 let mut out = MultisampleState::new();
1300 out.count = Some(state.count);
1301 out.mask = Some(state.mask.try_into().unwrap_or(u32::MAX));
1302 out.alpha_to_coverage_enabled = Some(state.alpha_to_coverage_enabled);
1303 out
1304}
1305
1306fn map_primitive_state(state: wgpu::PrimitiveState) -> PrimitiveState {
1307 let mut out = PrimitiveState::new();
1308 out.topology = Some(map_primitive_topology(state.topology));
1309 out.strip_index_format = state.strip_index_format.map(map_index_format);
1310 out.front_face = Some(map_front_face(state.front_face));
1311 out.cull_mode = Some(map_cull_mode(state.cull_mode));
1312 out.unclipped_depth = Some(state.unclipped_depth);
1313 out
1314}
1315
1316fn map_render_pipeline_descriptor(
1317 desc: &wgpu::RenderPipelineDescriptor<'_>,
1318) -> RenderPipelineDescriptor {
1319 let mut out = RenderPipelineDescriptor::new();
1320 out.label = label_to_string(desc.label);
1321 out.layout = desc.layout.map(expect_pipeline_layout_from_api);
1322 out.vertex = Some(map_vertex_state(&desc.vertex));
1323 out.primitive = Some(map_primitive_state(desc.primitive));
1324 out.depth_stencil = desc.depth_stencil.as_ref().map(map_depth_stencil_state);
1325 out.multisample = Some(map_multisample_state(desc.multisample));
1326 out.fragment = desc.fragment.as_ref().map(map_fragment_state);
1327 out
1328}
1329
1330fn map_compute_pipeline_descriptor(
1331 desc: &wgpu::ComputePipelineDescriptor<'_>,
1332) -> ComputePipelineDescriptor {
1333 let mut compute = ComputeState::new();
1334 compute.module = Some(expect_shader_module_from_api(desc.module));
1335 compute.entry_point = desc.entry_point.map(str::to_string);
1336 compute.constants = Some(
1337 desc.compilation_options
1338 .constants
1339 .iter()
1340 .map(|(k, v)| {
1341 let mut entry = ConstantEntry::new();
1342 entry.key = Some(k.to_string());
1343 entry.value = Some(*v);
1344 entry
1345 })
1346 .collect(),
1347 );
1348
1349 let mut out = ComputePipelineDescriptor::new();
1350 out.label = label_to_string(desc.label);
1351 out.layout = desc.layout.map(expect_pipeline_layout_from_api);
1352 out.compute = Some(compute);
1353 out
1354}
1355
1356fn map_command_encoder_descriptor(
1357 desc: &wgpu::CommandEncoderDescriptor<'_>,
1358) -> CommandEncoderDescriptor {
1359 let mut out = CommandEncoderDescriptor::new();
1360 out.label = label_to_string(desc.label);
1361 out
1362}
1363
1364fn map_render_bundle_encoder_descriptor(
1365 desc: &wgpu::RenderBundleEncoderDescriptor<'_>,
1366) -> RenderBundleEncoderDescriptor {
1367 let (depth_stencil_format, depth_read_only, stencil_read_only) = match desc.depth_stencil {
1368 Some(depth_stencil) => (
1369 Some(map_texture_format(depth_stencil.format)),
1370 Some(depth_stencil.depth_read_only),
1371 Some(depth_stencil.stencil_read_only),
1372 ),
1373 None => (None, None, None),
1374 };
1375 let mut out = RenderBundleEncoderDescriptor::new();
1376 out.label = label_to_string(desc.label);
1377 out.color_formats = Some(
1378 desc.color_formats
1379 .iter()
1380 .map(|v| {
1381 v.map(map_texture_format)
1382 .unwrap_or(TextureFormat::Undefined)
1383 })
1384 .collect(),
1385 );
1386 out.depth_stencil_format = depth_stencil_format;
1387 out.sample_count = Some(desc.sample_count);
1388 out.depth_read_only = depth_read_only;
1389 out.stencil_read_only = stencil_read_only;
1390 out
1391}
1392
1393fn map_render_pass_color_attachment(
1394 attachment: &wgpu::RenderPassColorAttachment<'_>,
1395) -> RenderPassColorAttachment {
1396 let (load_op, clear_value) = match attachment.ops.load {
1397 wgpu::LoadOp::Load => (LoadOp::Load, None),
1398 wgpu::LoadOp::Clear(value) => (LoadOp::Clear, Some(map_color(value))),
1399 wgpu::LoadOp::DontCare(_) => (LoadOp::Load, None),
1400 };
1401 let mut out = RenderPassColorAttachment::new();
1402 out.view = Some(expect_texture_view_from_api(attachment.view));
1403 if let Some(depth_slice) = attachment.depth_slice {
1404 out.depth_slice = Some(depth_slice);
1405 }
1406 out.resolve_target = attachment.resolve_target.map(expect_texture_view_from_api);
1407 out.load_op = Some(load_op);
1408 out.store_op = Some(map_store_op(attachment.ops.store));
1409 out.clear_value = clear_value;
1410 out
1411}
1412
1413fn map_render_pass_depth_stencil_attachment(
1414 attachment: &wgpu::RenderPassDepthStencilAttachment<'_>,
1415) -> RenderPassDepthStencilAttachment {
1416 let depth_read_only = attachment.depth_ops.is_none();
1417 let stencil_read_only = attachment.stencil_ops.is_none();
1418 let (depth_load_op, depth_store_op, depth_clear_value) = match attachment.depth_ops.as_ref() {
1419 Some(ops) => match ops.load {
1420 wgpu::LoadOp::Load => (Some(LoadOp::Load), Some(map_store_op(ops.store)), None),
1421 wgpu::LoadOp::Clear(value) => (
1422 Some(LoadOp::Clear),
1423 Some(map_store_op(ops.store)),
1424 Some(value),
1425 ),
1426 wgpu::LoadOp::DontCare(_) => (Some(LoadOp::Load), Some(map_store_op(ops.store)), None),
1427 },
1428 None => (None, None, None),
1429 };
1430 let (stencil_load_op, stencil_store_op, stencil_clear_value) = match attachment
1431 .stencil_ops
1432 .as_ref()
1433 {
1434 Some(ops) => match ops.load {
1435 wgpu::LoadOp::Load => (Some(LoadOp::Load), Some(map_store_op(ops.store)), None),
1436 wgpu::LoadOp::Clear(value) => (
1437 Some(LoadOp::Clear),
1438 Some(map_store_op(ops.store)),
1439 Some(value),
1440 ),
1441 wgpu::LoadOp::DontCare(_) => (Some(LoadOp::Load), Some(map_store_op(ops.store)), None),
1442 },
1443 None => (None, None, None),
1444 };
1445 let mut out = RenderPassDepthStencilAttachment::new();
1446 out.view = Some(expect_texture_view_from_api(attachment.view));
1447 out.depth_load_op = depth_load_op;
1448 out.depth_store_op = depth_store_op;
1449 out.depth_clear_value = depth_clear_value;
1450 out.depth_read_only = Some(depth_read_only);
1451 out.stencil_load_op = stencil_load_op;
1452 out.stencil_store_op = stencil_store_op;
1453 out.stencil_clear_value = stencil_clear_value;
1454 out.stencil_read_only = Some(stencil_read_only);
1455 out
1456}
1457
1458fn map_render_pass_descriptor(desc: &wgpu::RenderPassDescriptor<'_>) -> RenderPassDescriptor {
1459 let mut out = RenderPassDescriptor::new();
1460 out.label = label_to_string(desc.label);
1461 out.color_attachments = Some(
1462 desc.color_attachments
1463 .iter()
1464 .map(|att| {
1465 att.as_ref()
1466 .map(map_render_pass_color_attachment)
1467 .unwrap_or_default()
1468 })
1469 .collect(),
1470 );
1471 out.depth_stencil_attachment = desc
1472 .depth_stencil_attachment
1473 .as_ref()
1474 .map(map_render_pass_depth_stencil_attachment);
1475 out.occlusion_query_set = desc.occlusion_query_set.map(expect_query_set_from_api);
1476 out.timestamp_writes = None;
1477 out
1478}
1479
1480fn map_compute_pass_descriptor(desc: &wgpu::ComputePassDescriptor<'_>) -> ComputePassDescriptor {
1481 let mut out = ComputePassDescriptor::new();
1482 out.label = label_to_string(desc.label);
1483 out.timestamp_writes = None;
1484 out
1485}
1486
1487fn map_surface_configuration(config: &wgpu::SurfaceConfiguration) -> SurfaceConfiguration {
1488 let mut out = SurfaceConfiguration::new();
1489 out.format = Some(map_texture_format(config.format));
1490 out.usage = Some(map_texture_usages(config.usage));
1491 out.width = Some(config.width);
1492 out.height = Some(config.height);
1493 out.present_mode = Some(match config.present_mode {
1494 wgpu::PresentMode::Fifo => PresentMode::Fifo,
1495 wgpu::PresentMode::Mailbox => PresentMode::Mailbox,
1496 wgpu::PresentMode::Immediate => PresentMode::Immediate,
1497 wgpu::PresentMode::AutoVsync => PresentMode::Fifo,
1498 wgpu::PresentMode::AutoNoVsync => PresentMode::Immediate,
1499 _ => PresentMode::Fifo,
1500 });
1501 out.alpha_mode = Some(match config.alpha_mode {
1502 wgpu::CompositeAlphaMode::Auto => CompositeAlphaMode::Auto,
1503 wgpu::CompositeAlphaMode::Opaque => CompositeAlphaMode::Opaque,
1504 wgpu::CompositeAlphaMode::PreMultiplied => CompositeAlphaMode::Premultiplied,
1505 wgpu::CompositeAlphaMode::PostMultiplied => CompositeAlphaMode::Premultiplied,
1506 wgpu::CompositeAlphaMode::Inherit => CompositeAlphaMode::Inherit,
1507 _ => CompositeAlphaMode::Auto,
1508 });
1509 out.view_formats = Some(
1510 config
1511 .view_formats
1512 .iter()
1513 .copied()
1514 .map(map_texture_format)
1515 .collect(),
1516 );
1517 out
1518}
1519
1520fn map_surface_capabilities(caps: SurfaceCapabilities) -> wgpu::SurfaceCapabilities {
1521 wgpu::SurfaceCapabilities {
1522 formats: caps
1523 .formats
1524 .clone()
1525 .unwrap_or_default()
1526 .iter()
1527 .copied()
1528 .map(map_texture_format_to_wgpu)
1529 .collect(),
1530 present_modes: caps
1531 .present_modes
1532 .clone()
1533 .unwrap_or_default()
1534 .iter()
1535 .copied()
1536 .map(|m| match m {
1537 PresentMode::Fifo => wgpu::PresentMode::Fifo,
1538 PresentMode::Mailbox => wgpu::PresentMode::Mailbox,
1539 PresentMode::Immediate => wgpu::PresentMode::Immediate,
1540 PresentMode::FifoRelaxed => wgpu::PresentMode::AutoVsync,
1541 _ => wgpu::PresentMode::Fifo,
1542 })
1543 .collect(),
1544 alpha_modes: caps
1545 .alpha_modes
1546 .clone()
1547 .unwrap_or_default()
1548 .iter()
1549 .copied()
1550 .map(|m| match m {
1551 CompositeAlphaMode::Auto => wgpu::CompositeAlphaMode::Auto,
1552 CompositeAlphaMode::Opaque => wgpu::CompositeAlphaMode::Opaque,
1553 CompositeAlphaMode::Premultiplied => wgpu::CompositeAlphaMode::PreMultiplied,
1554 CompositeAlphaMode::Unpremultiplied => wgpu::CompositeAlphaMode::PostMultiplied,
1555 CompositeAlphaMode::Inherit => wgpu::CompositeAlphaMode::Inherit,
1556 _ => wgpu::CompositeAlphaMode::Auto,
1557 })
1558 .collect(),
1559 usages: map_texture_usage_to_wgpu(caps.usages.unwrap_or(TextureUsage::RENDER_ATTACHMENT)),
1560 }
1561}
1562
1563fn map_compilation_info(info: &CompilationInfo) -> wgpu::CompilationInfo {
1564 wgpu::CompilationInfo {
1565 messages: info
1566 .messages
1567 .as_ref()
1568 .map(|messages| {
1569 messages
1570 .iter()
1571 .map(|message| wgpu::CompilationMessage {
1572 message: message.message.clone().unwrap_or_default(),
1573 message_type: match message.r#type.unwrap_or(CompilationMessageType::Info) {
1574 CompilationMessageType::Error => wgpu::CompilationMessageType::Error,
1575 CompilationMessageType::Warning => {
1576 wgpu::CompilationMessageType::Warning
1577 }
1578 CompilationMessageType::Info => wgpu::CompilationMessageType::Info,
1579 },
1580 location: Some(wgpu::SourceLocation {
1581 line_number: message.line_num.unwrap_or(0) as u32,
1582 line_position: message.line_pos.unwrap_or(0) as u32,
1583 offset: message.offset.unwrap_or(0) as u32,
1584 length: message.length.unwrap_or(0) as u32,
1585 }),
1586 })
1587 .collect()
1588 })
1589 .unwrap_or_default(),
1590 }
1591}
1592
1593fn map_uncaptured_error(error_type: ErrorType, message: String) -> wgpu::Error {
1594 match error_type {
1595 ErrorType::OutOfMemory => wgpu::Error::OutOfMemory {
1596 source: Box::new(DawnError(message)),
1597 },
1598 ErrorType::Validation => wgpu::Error::Validation {
1599 source: Box::new(DawnError(message.clone())),
1600 description: message,
1601 },
1602 ErrorType::Internal | ErrorType::Unknown => wgpu::Error::Internal {
1603 source: Box::new(DawnError(message.clone())),
1604 description: message,
1605 },
1606 ErrorType::NoError => wgpu::Error::Internal {
1607 source: Box::new(DawnError("no error".to_string())),
1608 description: "no error".to_string(),
1609 },
1610 }
1611}
1612
1613fn map_limits_to_dawn(limits: &wgpu::Limits) -> Limits {
1614 let mut out = Limits::new();
1615 out.max_texture_dimension_1d = Some(limits.max_texture_dimension_1d);
1616 out.max_texture_dimension_2d = Some(limits.max_texture_dimension_2d);
1617 out.max_texture_dimension_3d = Some(limits.max_texture_dimension_3d);
1618 out.max_texture_array_layers = Some(limits.max_texture_array_layers);
1619 out.max_bind_groups = Some(limits.max_bind_groups);
1620 out.max_bindings_per_bind_group = Some(limits.max_bindings_per_bind_group);
1621 out.max_dynamic_uniform_buffers_per_pipeline_layout =
1622 Some(limits.max_dynamic_uniform_buffers_per_pipeline_layout);
1623 out.max_dynamic_storage_buffers_per_pipeline_layout =
1624 Some(limits.max_dynamic_storage_buffers_per_pipeline_layout);
1625 out.max_sampled_textures_per_shader_stage = Some(limits.max_sampled_textures_per_shader_stage);
1626 out.max_samplers_per_shader_stage = Some(limits.max_samplers_per_shader_stage);
1627 out.max_storage_buffers_per_shader_stage = Some(limits.max_storage_buffers_per_shader_stage);
1628 out.max_storage_textures_per_shader_stage = Some(limits.max_storage_textures_per_shader_stage);
1629 out.max_uniform_buffers_per_shader_stage = Some(limits.max_uniform_buffers_per_shader_stage);
1630 out.max_uniform_buffer_binding_size = Some(limits.max_uniform_buffer_binding_size as u64);
1631 out.max_storage_buffer_binding_size = Some(limits.max_storage_buffer_binding_size as u64);
1632 out.min_uniform_buffer_offset_alignment = Some(limits.min_uniform_buffer_offset_alignment);
1633 out.min_storage_buffer_offset_alignment = Some(limits.min_storage_buffer_offset_alignment);
1634 out.max_vertex_buffers = Some(limits.max_vertex_buffers);
1635 out.max_buffer_size = Some(limits.max_buffer_size);
1636 out.max_vertex_attributes = Some(limits.max_vertex_attributes);
1637 out.max_vertex_buffer_array_stride = Some(limits.max_vertex_buffer_array_stride);
1638 out.max_inter_stage_shader_variables = Some(limits.max_inter_stage_shader_components);
1639 out.max_color_attachments = Some(limits.max_color_attachments);
1640 out.max_color_attachment_bytes_per_sample = Some(limits.max_color_attachment_bytes_per_sample);
1641 out.max_compute_workgroup_storage_size = Some(limits.max_compute_workgroup_storage_size);
1642 out.max_compute_invocations_per_workgroup = Some(limits.max_compute_invocations_per_workgroup);
1643 out.max_compute_workgroup_size_x = Some(limits.max_compute_workgroup_size_x);
1644 out.max_compute_workgroup_size_y = Some(limits.max_compute_workgroup_size_y);
1645 out.max_compute_workgroup_size_z = Some(limits.max_compute_workgroup_size_z);
1646 out.max_compute_workgroups_per_dimension = Some(limits.max_compute_workgroups_per_dimension);
1647 out.max_bind_groups_plus_vertex_buffers =
1648 Some(limits.max_bind_groups + limits.max_vertex_buffers);
1649 out
1650}
1651
1652fn map_limits_to_wgpu(limits: &Limits) -> wgpu::Limits {
1653 let mut out = wgpu::Limits::default();
1654 if let Some(value) = limits.max_texture_dimension_1d {
1655 out.max_texture_dimension_1d = value;
1656 }
1657 if let Some(value) = limits.max_texture_dimension_2d {
1658 out.max_texture_dimension_2d = value;
1659 }
1660 if let Some(value) = limits.max_texture_dimension_3d {
1661 out.max_texture_dimension_3d = value;
1662 }
1663 if let Some(value) = limits.max_texture_array_layers {
1664 out.max_texture_array_layers = value;
1665 }
1666 if let Some(value) = limits.max_bind_groups {
1667 out.max_bind_groups = value;
1668 }
1669 if let Some(value) = limits.max_bindings_per_bind_group {
1670 out.max_bindings_per_bind_group = value;
1671 }
1672 if let Some(value) = limits.max_dynamic_uniform_buffers_per_pipeline_layout {
1673 out.max_dynamic_uniform_buffers_per_pipeline_layout = value;
1674 }
1675 if let Some(value) = limits.max_dynamic_storage_buffers_per_pipeline_layout {
1676 out.max_dynamic_storage_buffers_per_pipeline_layout = value;
1677 }
1678 if let Some(value) = limits.max_sampled_textures_per_shader_stage {
1679 out.max_sampled_textures_per_shader_stage = value;
1680 }
1681 if let Some(value) = limits.max_samplers_per_shader_stage {
1682 out.max_samplers_per_shader_stage = value;
1683 }
1684 if let Some(value) = limits.max_storage_buffers_per_shader_stage {
1685 out.max_storage_buffers_per_shader_stage = value;
1686 }
1687 if let Some(value) = limits.max_storage_textures_per_shader_stage {
1688 out.max_storage_textures_per_shader_stage = value;
1689 }
1690 if let Some(value) = limits.max_uniform_buffers_per_shader_stage {
1691 out.max_uniform_buffers_per_shader_stage = value;
1692 }
1693 if let Some(value) = limits.max_uniform_buffer_binding_size {
1694 out.max_uniform_buffer_binding_size = value as u32;
1695 }
1696 if let Some(value) = limits.max_storage_buffer_binding_size {
1697 out.max_storage_buffer_binding_size = value as u32;
1698 }
1699 if let Some(value) = limits.min_uniform_buffer_offset_alignment {
1700 out.min_uniform_buffer_offset_alignment = value;
1701 }
1702 if let Some(value) = limits.min_storage_buffer_offset_alignment {
1703 out.min_storage_buffer_offset_alignment = value;
1704 }
1705 if let Some(value) = limits.max_vertex_buffers {
1706 out.max_vertex_buffers = value;
1707 }
1708 if let Some(value) = limits.max_buffer_size {
1709 out.max_buffer_size = value;
1710 }
1711 if let Some(value) = limits.max_vertex_attributes {
1712 out.max_vertex_attributes = value;
1713 }
1714 if let Some(value) = limits.max_vertex_buffer_array_stride {
1715 out.max_vertex_buffer_array_stride = value;
1716 }
1717 if let Some(value) = limits.max_inter_stage_shader_variables {
1718 out.max_inter_stage_shader_components = value;
1719 }
1720 if let Some(value) = limits.max_color_attachments {
1721 out.max_color_attachments = value;
1722 }
1723 if let Some(value) = limits.max_color_attachment_bytes_per_sample {
1724 out.max_color_attachment_bytes_per_sample = value;
1725 }
1726 if let Some(value) = limits.max_compute_workgroup_storage_size {
1727 out.max_compute_workgroup_storage_size = value;
1728 }
1729 if let Some(value) = limits.max_compute_invocations_per_workgroup {
1730 out.max_compute_invocations_per_workgroup = value;
1731 }
1732 if let Some(value) = limits.max_compute_workgroup_size_x {
1733 out.max_compute_workgroup_size_x = value;
1734 }
1735 if let Some(value) = limits.max_compute_workgroup_size_y {
1736 out.max_compute_workgroup_size_y = value;
1737 }
1738 if let Some(value) = limits.max_compute_workgroup_size_z {
1739 out.max_compute_workgroup_size_z = value;
1740 }
1741 if let Some(value) = limits.max_compute_workgroups_per_dimension {
1742 out.max_compute_workgroups_per_dimension = value;
1743 }
1744 out
1745}
1746
1747fn map_features_to_dawn(features: wgpu::Features) -> Vec<FeatureName> {
1748 let mut out = Vec::new();
1749 if features.contains(wgpu::Features::DEPTH_CLIP_CONTROL) {
1750 out.push(FeatureName::DepthClipControl);
1751 }
1752 if features.contains(wgpu::Features::DEPTH32FLOAT_STENCIL8) {
1753 out.push(FeatureName::Depth32FloatStencil8);
1754 }
1755 if features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC) {
1756 out.push(FeatureName::TextureCompressionBc);
1757 }
1758 if features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC_SLICED_3D) {
1759 out.push(FeatureName::TextureCompressionBcSliced3D);
1760 }
1761 if features.contains(wgpu::Features::TEXTURE_COMPRESSION_ETC2) {
1762 out.push(FeatureName::TextureCompressionEtc2);
1763 }
1764 if features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC) {
1765 out.push(FeatureName::TextureCompressionAstc);
1766 }
1767 if features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC_HDR) {
1768 out.push(FeatureName::TextureCompressionAstc);
1769 }
1770 if features.contains(wgpu::Features::TIMESTAMP_QUERY) {
1771 out.push(FeatureName::TimestampQuery);
1772 }
1773 if features.contains(wgpu::Features::INDIRECT_FIRST_INSTANCE) {
1774 out.push(FeatureName::IndirectFirstInstance);
1775 }
1776 if features.contains(wgpu::Features::SHADER_F16) {
1777 out.push(FeatureName::ShaderF16);
1778 }
1779 if features.contains(wgpu::Features::RG11B10UFLOAT_RENDERABLE) {
1780 out.push(FeatureName::Rg11B10UfloatRenderable);
1781 }
1782 if features.contains(wgpu::Features::BGRA8UNORM_STORAGE) {
1783 out.push(FeatureName::Bgra8UnormStorage);
1784 }
1785 if features.contains(wgpu::Features::FLOAT32_FILTERABLE) {
1786 out.push(FeatureName::Float32Filterable);
1787 }
1788 if features.contains(wgpu::Features::CLIP_DISTANCES) {
1789 out.push(FeatureName::ClipDistances);
1790 }
1791 if features.contains(wgpu::Features::DUAL_SOURCE_BLENDING) {
1792 out.push(FeatureName::DualSourceBlending);
1793 }
1794 if features.contains(wgpu::Features::SUBGROUP) {
1795 out.push(FeatureName::Subgroups);
1796 }
1797 if features.contains(wgpu::Features::TEXTURE_FORMAT_16BIT_NORM) {
1798 out.push(FeatureName::Unorm16TextureFormats);
1799 }
1800 if features.contains(wgpu::Features::MULTI_DRAW_INDIRECT_COUNT) {
1801 out.push(FeatureName::MultiDrawIndirect);
1802 }
1803 out
1804}
1805
1806fn map_features_to_wgpu(features: &SupportedFeatures) -> wgpu::Features {
1807 let mut out = wgpu::Features::empty();
1808 if let Some(list) = &features.features {
1809 for feature in list {
1810 match feature {
1811 FeatureName::DepthClipControl => out |= wgpu::Features::DEPTH_CLIP_CONTROL,
1812 FeatureName::Depth32FloatStencil8 => out |= wgpu::Features::DEPTH32FLOAT_STENCIL8,
1813 FeatureName::TextureCompressionBc => out |= wgpu::Features::TEXTURE_COMPRESSION_BC,
1814 FeatureName::TextureCompressionBcSliced3D => {
1815 out |= wgpu::Features::TEXTURE_COMPRESSION_BC_SLICED_3D
1816 }
1817 FeatureName::TextureCompressionEtc2 => {
1818 out |= wgpu::Features::TEXTURE_COMPRESSION_ETC2
1819 }
1820 FeatureName::TextureCompressionAstc => {
1821 out |= wgpu::Features::TEXTURE_COMPRESSION_ASTC
1822 }
1823 FeatureName::TimestampQuery => out |= wgpu::Features::TIMESTAMP_QUERY,
1824 FeatureName::IndirectFirstInstance => {
1825 out |= wgpu::Features::INDIRECT_FIRST_INSTANCE
1826 }
1827 FeatureName::ShaderF16 => out |= wgpu::Features::SHADER_F16,
1828 FeatureName::Rg11B10UfloatRenderable => {
1829 out |= wgpu::Features::RG11B10UFLOAT_RENDERABLE
1830 }
1831 FeatureName::Bgra8UnormStorage => out |= wgpu::Features::BGRA8UNORM_STORAGE,
1832 FeatureName::Float32Filterable => out |= wgpu::Features::FLOAT32_FILTERABLE,
1833 FeatureName::Float32Blendable => {}
1834 FeatureName::ClipDistances => out |= wgpu::Features::CLIP_DISTANCES,
1835 FeatureName::DualSourceBlending => out |= wgpu::Features::DUAL_SOURCE_BLENDING,
1836 FeatureName::Subgroups => out |= wgpu::Features::SUBGROUP,
1837 FeatureName::Unorm16TextureFormats => {
1838 out |= wgpu::Features::TEXTURE_FORMAT_16BIT_NORM
1839 }
1840 FeatureName::MultiDrawIndirect => out |= wgpu::Features::MULTI_DRAW_INDIRECT_COUNT,
1841 _ => {}
1842 }
1843 }
1844 }
1845 out
1846}
1847
1848fn bytes_to_u32(data: &[u8]) -> Vec<u32> {
1849 let mut out = Vec::with_capacity((data.len() + 3) / 4);
1850 for chunk in data.chunks(4) {
1851 let mut buf = [0u8; 4];
1852 buf[..chunk.len()].copy_from_slice(chunk);
1853 out.push(u32::from_le_bytes(buf));
1854 }
1855 out
1856}
1857
1858fn dispatch_adapter(adapter: Adapter) -> DispatchAdapter {
1859 DispatchAdapter::custom(DawnAdapter { inner: adapter })
1860}
1861
1862fn dispatch_device(device: Device) -> DispatchDevice {
1863 DispatchDevice::custom(DawnDevice { inner: device })
1864}
1865
1866fn dispatch_queue(queue: Queue) -> DispatchQueue {
1867 DispatchQueue::custom(DawnQueue { inner: queue })
1868}
1869
1870fn dispatch_surface(surface: DawnSurface) -> DispatchSurface {
1871 DispatchSurface::custom(surface)
1872}
1873
1874fn dispatch_shader_module(module: ShaderModule) -> DispatchShaderModule {
1875 DispatchShaderModule::custom(DawnShaderModule { inner: module })
1876}
1877
1878fn dispatch_bind_group_layout(layout: BindGroupLayout) -> DispatchBindGroupLayout {
1879 DispatchBindGroupLayout::custom(DawnBindGroupLayout { inner: layout })
1880}
1881
1882fn dispatch_bind_group(group: BindGroup) -> DispatchBindGroup {
1883 DispatchBindGroup::custom(DawnBindGroup { inner: group })
1884}
1885
1886fn dispatch_texture_view(view: TextureView) -> DispatchTextureView {
1887 DispatchTextureView::custom(DawnTextureView { inner: view })
1888}
1889
1890fn dispatch_sampler(sampler: Sampler) -> DispatchSampler {
1891 DispatchSampler::custom(DawnSampler { inner: sampler })
1892}
1893
1894fn dispatch_buffer(buffer: Buffer) -> DispatchBuffer {
1895 DispatchBuffer::custom(DawnBuffer { inner: buffer })
1896}
1897
1898fn dispatch_texture(texture: Texture) -> DispatchTexture {
1899 DispatchTexture::custom(DawnTexture { inner: texture })
1900}
1901
1902fn dispatch_external_texture(texture: ExternalTexture) -> DispatchExternalTexture {
1903 DispatchExternalTexture::custom(DawnExternalTexture { inner: texture })
1904}
1905
1906fn dispatch_query_set(query_set: QuerySet) -> DispatchQuerySet {
1907 DispatchQuerySet::custom(DawnQuerySet { inner: query_set })
1908}
1909
1910fn dispatch_pipeline_layout(layout: PipelineLayout) -> DispatchPipelineLayout {
1911 DispatchPipelineLayout::custom(DawnPipelineLayout { inner: layout })
1912}
1913
1914fn dispatch_render_pipeline(pipeline: RenderPipeline) -> DispatchRenderPipeline {
1915 DispatchRenderPipeline::custom(DawnRenderPipeline { inner: pipeline })
1916}
1917
1918fn dispatch_compute_pipeline(pipeline: ComputePipeline) -> DispatchComputePipeline {
1919 DispatchComputePipeline::custom(DawnComputePipeline { inner: pipeline })
1920}
1921
1922fn dispatch_command_encoder(encoder: CommandEncoder) -> DispatchCommandEncoder {
1923 DispatchCommandEncoder::custom(DawnCommandEncoder { inner: encoder })
1924}
1925
1926fn dispatch_command_buffer(buffer: CommandBuffer) -> DispatchCommandBuffer {
1927 DispatchCommandBuffer::custom(DawnCommandBuffer { inner: buffer })
1928}
1929
1930fn dispatch_compute_pass(pass: ComputePassEncoder) -> DispatchComputePass {
1931 DispatchComputePass::custom(DawnComputePass {
1932 inner: pass,
1933 ended: false,
1934 })
1935}
1936
1937fn dispatch_render_pass(pass: RenderPassEncoder) -> DispatchRenderPass {
1938 DispatchRenderPass::custom(DawnRenderPass {
1939 inner: pass,
1940 ended: false,
1941 })
1942}
1943
1944fn dispatch_render_bundle_encoder(encoder: RenderBundleEncoder) -> DispatchRenderBundleEncoder {
1945 DispatchRenderBundleEncoder::custom(DawnRenderBundleEncoder { inner: encoder })
1946}
1947
1948fn dispatch_render_bundle(bundle: RenderBundle) -> DispatchRenderBundle {
1949 DispatchRenderBundle::custom(DawnRenderBundle { inner: bundle })
1950}
1951
1952fn dispatch_surface_output_detail(surface: Surface) -> DispatchSurfaceOutputDetail {
1953 DispatchSurfaceOutputDetail::custom(DawnSurfaceOutputDetail { surface })
1954}
1955
1956fn dispatch_queue_write_buffer(data: Vec<u8>) -> DispatchQueueWriteBuffer {
1957 DispatchQueueWriteBuffer::custom(DawnQueueWriteBuffer { inner: data })
1958}
1959
1960fn dispatch_buffer_mapped_range(ptr: *mut u8, size: usize) -> DispatchBufferMappedRange {
1961 DispatchBufferMappedRange::custom(DawnBufferMappedRange { data: ptr, size })
1962}
1963
1964fn dispatch_pipeline_cache() -> DispatchPipelineCache {
1965 DispatchPipelineCache::custom(DawnPipelineCache)
1966}
1967
1968fn dispatch_blas() -> DispatchBlas {
1969 DispatchBlas::custom(DawnBlas)
1970}
1971
1972fn dispatch_tlas() -> DispatchTlas {
1973 DispatchTlas::custom(DawnTlas)
1974}
1975
1976fn expect_adapter(adapter: &DispatchAdapter) -> Adapter {
1977 adapter
1978 .as_custom::<DawnAdapter>()
1979 .expect("wgpu-compat: adapter not dawn")
1980 .inner
1981 .clone()
1982}
1983
1984fn expect_device(device: &DispatchDevice) -> Device {
1985 device
1986 .as_custom::<DawnDevice>()
1987 .expect("wgpu-compat: device not dawn")
1988 .inner
1989 .clone()
1990}
1991
1992fn expect_queue(queue: &DispatchQueue) -> Queue {
1993 queue
1994 .as_custom::<DawnQueue>()
1995 .expect("wgpu-compat: queue not dawn")
1996 .inner
1997 .clone()
1998}
1999
2000fn expect_surface(surface: &DispatchSurface) -> DawnSurface {
2001 surface
2002 .as_custom::<DawnSurface>()
2003 .expect("wgpu-compat: surface not dawn")
2004 .clone()
2005}
2006
2007fn expect_shader_module(module: &DispatchShaderModule) -> ShaderModule {
2008 module
2009 .as_custom::<DawnShaderModule>()
2010 .expect("wgpu-compat: shader module not dawn")
2011 .inner
2012 .clone()
2013}
2014
2015fn expect_bind_group_layout(layout: &DispatchBindGroupLayout) -> BindGroupLayout {
2016 layout
2017 .as_custom::<DawnBindGroupLayout>()
2018 .expect("wgpu-compat: bind group layout not dawn")
2019 .inner
2020 .clone()
2021}
2022
2023fn expect_bind_group(group: &DispatchBindGroup) -> BindGroup {
2024 group
2025 .as_custom::<DawnBindGroup>()
2026 .expect("wgpu-compat: bind group not dawn")
2027 .inner
2028 .clone()
2029}
2030
2031fn expect_texture_view(view: &DispatchTextureView) -> TextureView {
2032 view.as_custom::<DawnTextureView>()
2033 .expect("wgpu-compat: texture view not dawn")
2034 .inner
2035 .clone()
2036}
2037
2038fn expect_sampler(sampler: &DispatchSampler) -> Sampler {
2039 sampler
2040 .as_custom::<DawnSampler>()
2041 .expect("wgpu-compat: sampler not dawn")
2042 .inner
2043 .clone()
2044}
2045
2046fn expect_buffer(buffer: &DispatchBuffer) -> Buffer {
2047 buffer
2048 .as_custom::<DawnBuffer>()
2049 .expect("wgpu-compat: buffer not dawn")
2050 .inner
2051 .clone()
2052}
2053
2054fn expect_texture(texture: &DispatchTexture) -> Texture {
2055 texture
2056 .as_custom::<DawnTexture>()
2057 .expect("wgpu-compat: texture not dawn")
2058 .inner
2059 .clone()
2060}
2061
2062fn expect_external_texture(texture: &DispatchExternalTexture) -> ExternalTexture {
2063 texture
2064 .as_custom::<DawnExternalTexture>()
2065 .expect("wgpu-compat: external texture not dawn")
2066 .inner
2067 .clone()
2068}
2069
2070fn expect_query_set(query_set: &DispatchQuerySet) -> QuerySet {
2071 query_set
2072 .as_custom::<DawnQuerySet>()
2073 .expect("wgpu-compat: query set not dawn")
2074 .inner
2075 .clone()
2076}
2077
2078fn expect_pipeline_layout(layout: &DispatchPipelineLayout) -> PipelineLayout {
2079 layout
2080 .as_custom::<DawnPipelineLayout>()
2081 .expect("wgpu-compat: pipeline layout not dawn")
2082 .inner
2083 .clone()
2084}
2085
2086fn expect_render_pipeline(pipeline: &DispatchRenderPipeline) -> RenderPipeline {
2087 pipeline
2088 .as_custom::<DawnRenderPipeline>()
2089 .expect("wgpu-compat: render pipeline not dawn")
2090 .inner
2091 .clone()
2092}
2093
2094fn expect_compute_pipeline(pipeline: &DispatchComputePipeline) -> ComputePipeline {
2095 pipeline
2096 .as_custom::<DawnComputePipeline>()
2097 .expect("wgpu-compat: compute pipeline not dawn")
2098 .inner
2099 .clone()
2100}
2101
2102fn expect_command_encoder(encoder: &DispatchCommandEncoder) -> CommandEncoder {
2103 encoder
2104 .as_custom::<DawnCommandEncoder>()
2105 .expect("wgpu-compat: command encoder not dawn")
2106 .inner
2107 .clone()
2108}
2109
2110fn expect_command_buffer(buffer: &DispatchCommandBuffer) -> CommandBuffer {
2111 buffer
2112 .as_custom::<DawnCommandBuffer>()
2113 .expect("wgpu-compat: command buffer not dawn")
2114 .inner
2115 .clone()
2116}
2117
2118fn expect_render_bundle(bundle: &DispatchRenderBundle) -> RenderBundle {
2119 bundle
2120 .as_custom::<DawnRenderBundle>()
2121 .expect("wgpu-compat: render bundle not dawn")
2122 .inner
2123 .clone()
2124}
2125
2126fn expect_surface_output_detail(detail: &DispatchSurfaceOutputDetail) -> Surface {
2127 detail
2128 .as_custom::<DawnSurfaceOutputDetail>()
2129 .expect("wgpu-compat: surface output detail not dawn")
2130 .surface
2131 .clone()
2132}
2133
2134fn expect_device_from_api(device: &wgpu::Device) -> Device {
2135 device
2136 .as_custom::<DawnDevice>()
2137 .expect("wgpu-compat: device not dawn")
2138 .inner
2139 .clone()
2140}
2141
2142fn expect_surface_from_api(surface: &wgpu::Surface) -> DawnSurface {
2143 surface
2144 .as_custom::<DawnSurface>()
2145 .expect("wgpu-compat: surface not dawn")
2146 .clone()
2147}
2148
2149fn expect_buffer_from_api(buffer: &wgpu::Buffer) -> Buffer {
2150 buffer
2151 .as_custom::<DawnBuffer>()
2152 .expect("wgpu-compat: buffer not dawn")
2153 .inner
2154 .clone()
2155}
2156
2157fn expect_texture_from_api(texture: &wgpu::Texture) -> Texture {
2158 texture
2159 .as_custom::<DawnTexture>()
2160 .expect("wgpu-compat: texture not dawn")
2161 .inner
2162 .clone()
2163}
2164
2165fn expect_texture_view_from_api(view: &wgpu::TextureView) -> TextureView {
2166 view.as_custom::<DawnTextureView>()
2167 .expect("wgpu-compat: texture view not dawn")
2168 .inner
2169 .clone()
2170}
2171
2172fn expect_sampler_from_api(sampler: &wgpu::Sampler) -> Sampler {
2173 sampler
2174 .as_custom::<DawnSampler>()
2175 .expect("wgpu-compat: sampler not dawn")
2176 .inner
2177 .clone()
2178}
2179
2180fn expect_bind_group_layout_from_api(layout: &wgpu::BindGroupLayout) -> BindGroupLayout {
2181 layout
2182 .as_custom::<DawnBindGroupLayout>()
2183 .expect("wgpu-compat: bind group layout not dawn")
2184 .inner
2185 .clone()
2186}
2187
2188fn expect_pipeline_layout_from_api(layout: &wgpu::PipelineLayout) -> PipelineLayout {
2189 layout
2190 .as_custom::<DawnPipelineLayout>()
2191 .expect("wgpu-compat: pipeline layout not dawn")
2192 .inner
2193 .clone()
2194}
2195
2196fn expect_shader_module_from_api(module: &wgpu::ShaderModule) -> ShaderModule {
2197 module
2198 .as_custom::<DawnShaderModule>()
2199 .expect("wgpu-compat: shader module not dawn")
2200 .inner
2201 .clone()
2202}
2203
2204fn expect_bind_group_from_api(group: &wgpu::BindGroup) -> BindGroup {
2205 group
2206 .as_custom::<DawnBindGroup>()
2207 .expect("wgpu-compat: bind group not dawn")
2208 .inner
2209 .clone()
2210}
2211
2212fn expect_query_set_from_api(query_set: &wgpu::QuerySet) -> QuerySet {
2213 query_set
2214 .as_custom::<DawnQuerySet>()
2215 .expect("wgpu-compat: query set not dawn")
2216 .inner
2217 .clone()
2218}
2219
2220impl InstanceInterface for DawnInstance {
2221 fn new(_desc: &wgpu::InstanceDescriptor) -> Self {
2222 let mut desc = InstanceDescriptor::new();
2223 desc.required_features = Some(vec![InstanceFeatureName::TimedWaitAny]);
2224 let instance = Instance::new(Some(&desc));
2225 Self { inner: instance }
2226 }
2227
2228 unsafe fn create_surface(
2229 &self,
2230 target: wgpu::SurfaceTargetUnsafe,
2231 ) -> Result<DispatchSurface, wgpu::CreateSurfaceError> {
2232 match target {
2233 #[cfg(target_os = "macos")]
2234 wgpu::SurfaceTargetUnsafe::CoreAnimationLayer(layer) => {
2235 let mut desc = SurfaceDescriptor::new();
2236 let source = SurfaceSourceMetalLayer { layer: Some(layer) };
2237 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2238 let surface = self.inner.create_surface(&desc);
2239 let dawn_surface = DawnSurface {
2240 inner: surface,
2241 metal_layer: None,
2242 };
2243 Ok(dispatch_surface(dawn_surface))
2244 }
2245 #[cfg(target_os = "macos")]
2246 wgpu::SurfaceTargetUnsafe::RawHandle {
2247 raw_window_handle, ..
2248 } => {
2249 use wgpu::rwh::RawWindowHandle;
2250 match raw_window_handle {
2251 RawWindowHandle::AppKit(handle) => {
2252 let layer =
2253 unsafe { raw_window_metal::Layer::from_ns_view(handle.ns_view) };
2254 let layer_ptr = layer.into_raw();
2255 let mut desc = SurfaceDescriptor::new();
2256 let source = SurfaceSourceMetalLayer {
2257 layer: Some(layer_ptr.as_ptr().cast()),
2258 };
2259 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2260 let surface = self.inner.create_surface(&desc);
2261 let handle = MetalLayerHandle {
2262 ptr: layer_ptr.as_ptr().cast(),
2263 };
2264 let dawn_surface = DawnSurface {
2265 inner: surface,
2266 metal_layer: Some(Arc::new(handle)),
2267 };
2268 Ok(dispatch_surface(dawn_surface))
2269 }
2270 _ => panic!("wgpu-compat: unsupported raw window handle on macOS"),
2271 }
2272 }
2273 #[cfg(target_os = "windows")]
2274 wgpu::SurfaceTargetUnsafe::RawHandle {
2275 raw_window_handle, ..
2276 } => {
2277 use wgpu::rwh::RawWindowHandle;
2278 match raw_window_handle {
2279 RawWindowHandle::Win32(handle) => {
2280 let mut desc = SurfaceDescriptor::new();
2281 let source = SurfaceSourceWindowsHWND {
2282 hinstance: Some(handle.hinstance.cast()),
2283 hwnd: Some(handle.hwnd.cast()),
2284 };
2285 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2286 let surface = self.inner.create_surface(&desc);
2287 let dawn_surface = DawnSurface { inner: surface };
2288 Ok(dispatch_surface(dawn_surface))
2289 }
2290 _ => panic!("wgpu-compat: unsupported raw window handle on Windows"),
2291 }
2292 }
2293 #[cfg(all(unix, not(target_vendor = "apple")))]
2294 wgpu::SurfaceTargetUnsafe::RawHandle {
2295 raw_display_handle,
2296 raw_window_handle,
2297 } => {
2298 use wgpu::rwh::{RawDisplayHandle, RawWindowHandle};
2299 match (raw_display_handle, raw_window_handle) {
2300 (RawDisplayHandle::Wayland(display), RawWindowHandle::Wayland(window)) => {
2301 let mut desc = SurfaceDescriptor::new();
2302 let source = SurfaceSourceWaylandSurface {
2303 display: Some(display.display.cast()),
2304 surface: Some(window.surface.cast()),
2305 };
2306 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2307 let surface = self.inner.create_surface(&desc);
2308 let dawn_surface = DawnSurface { inner: surface };
2309 Ok(dispatch_surface(dawn_surface))
2310 }
2311 (RawDisplayHandle::Xlib(display), RawWindowHandle::Xlib(window)) => {
2312 let mut desc = SurfaceDescriptor::new();
2313 let source = SurfaceSourceXlibWindow {
2314 display: Some(display.display.cast()),
2315 window: Some(window.window as u64),
2316 };
2317 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2318 let surface = self.inner.create_surface(&desc);
2319 let dawn_surface = DawnSurface { inner: surface };
2320 Ok(dispatch_surface(dawn_surface))
2321 }
2322 (RawDisplayHandle::Xcb(display), RawWindowHandle::Xcb(window)) => {
2323 let mut desc = SurfaceDescriptor::new();
2324 let source = SurfaceSourceXCBWindow {
2325 connection: Some(display.connection.cast()),
2326 window: Some(window.window),
2327 };
2328 desc = desc.with_extension(SurfaceDescriptorExtension::from(source));
2329 let surface = self.inner.create_surface(&desc);
2330 let dawn_surface = DawnSurface { inner: surface };
2331 Ok(dispatch_surface(dawn_surface))
2332 }
2333 _ => panic!("wgpu-compat: unsupported raw window handle on unix"),
2334 }
2335 }
2336 _ => panic!("wgpu-compat: unsupported surface target"),
2337 }
2338 }
2339
2340 fn request_adapter(
2341 &self,
2342 options: &wgpu::RequestAdapterOptions<'_, '_>,
2343 ) -> Pin<Box<dyn wgpu::custom::RequestAdapterFuture>> {
2344 let (future, shared) = CallbackFuture::new();
2345 let mut dawn_options = RequestAdapterOptions::new();
2346 dawn_options.power_preference = Some(map_power_preference(options.power_preference));
2347 dawn_options.force_fallback_adapter = Some(options.force_fallback_adapter);
2348 if let Some(surface) = options.compatible_surface {
2349 dawn_options.compatible_surface = Some(expect_surface_from_api(surface).inner);
2350 }
2351 let future_handle =
2352 self.inner
2353 .request_adapter(Some(&dawn_options), move |status, adapter, _message| {
2354 if status == RequestAdapterStatus::Success {
2355 let adapter = adapter.expect("wgpu-compat: missing adapter");
2356 complete_shared(&shared, Ok(dispatch_adapter(adapter)));
2357 } else {
2358 complete_shared(
2359 &shared,
2360 Err(wgpu::RequestAdapterError::NotFound {
2361 active_backends: wgpu::Backends::empty(),
2362 requested_backends: wgpu::Backends::empty(),
2363 supported_backends: wgpu::Backends::empty(),
2364 no_fallback_backends: wgpu::Backends::empty(),
2365 no_adapter_backends: wgpu::Backends::empty(),
2366 incompatible_surface_backends: wgpu::Backends::empty(),
2367 }),
2368 );
2369 }
2370 });
2371 let _ = self.inner.wait_any(
2372 Some(&mut [FutureWaitInfo {
2373 future: Some(future_handle),
2374 completed: None,
2375 }]),
2376 0,
2377 );
2378 Box::pin(future)
2379 }
2380
2381 fn poll_all_devices(&self, _force_wait: bool) -> bool {
2382 self.inner.process_events();
2383 true
2384 }
2385
2386 fn wgsl_language_features(&self) -> wgpu::WgslLanguageFeatures {
2387 let mut features = SupportedWGSLLanguageFeatures::new();
2388 self.inner.get_wgsl_language_features(&mut features);
2389 let mut out = wgpu::WgslLanguageFeatures::empty();
2390 if let Some(list) = features.features.as_ref() {
2391 for feature in list {
2392 if *feature == WGSLLanguageFeatureName::ReadonlyAndReadwriteStorageTextures {
2393 out |= wgpu::WgslLanguageFeatures::ReadOnlyAndReadWriteStorageTextures;
2394 }
2395 }
2396 }
2397 out
2398 }
2399
2400 fn enumerate_adapters(
2401 &self,
2402 _backends: wgpu::Backends,
2403 ) -> Pin<Box<dyn wgpu::custom::EnumerateAdapterFuture>> {
2404 let (future, shared) = CallbackFuture::new();
2405 complete_shared(&shared, Vec::new());
2406 Box::pin(future)
2407 }
2408}
2409
2410impl AdapterInterface for DawnAdapter {
2411 fn request_device(
2412 &self,
2413 desc: &wgpu::DeviceDescriptor<'_>,
2414 ) -> Pin<Box<dyn wgpu::custom::RequestDeviceFuture>> {
2415 let (future, shared) = CallbackFuture::new();
2416 let mut dawn_desc = DeviceDescriptor::new();
2417 dawn_desc.label = label_to_string(desc.label);
2418 if !desc.required_features.is_empty() {
2419 dawn_desc.required_features = Some(map_features_to_dawn(desc.required_features));
2420 }
2421 if desc.required_limits != wgpu::Limits::default() {
2422 dawn_desc.required_limits = Some(map_limits_to_dawn(&desc.required_limits));
2423 }
2424 let error_info = dawn_rs::UncapturedErrorCallbackInfo::new();
2425 error_info
2426 .callback
2427 .replace(Some(Box::new(|_devices, ty, message| {
2428 panic!("Uncaptured error {:?}: {}", ty, message);
2429 })));
2430 dawn_desc.uncaptured_error_callback_info = Some(error_info);
2431 let instance = self.inner.get_instance();
2432 let future_handle =
2433 self.inner
2434 .request_device(Some(&dawn_desc), move |status, device, message| {
2435 if status == RequestDeviceStatus::Success {
2436 let device = device.expect("wgpu-compat: missing device");
2437 let queue = device.get_queue();
2438 complete_shared(
2439 &shared,
2440 Ok((dispatch_device(device), dispatch_queue(queue))),
2441 );
2442 } else {
2443 panic!("wgpu-compat: request_device failed {}", message);
2444 }
2445 });
2446 let _ = instance.wait_any(
2447 Some(&mut [FutureWaitInfo {
2448 future: Some(future_handle),
2449 completed: None,
2450 }]),
2451 0,
2452 );
2453 Box::pin(future)
2454 }
2455
2456 fn is_surface_supported(&self, surface: &DispatchSurface) -> bool {
2457 surface.as_custom::<DawnSurface>().is_some()
2458 }
2459
2460 fn features(&self) -> wgpu::Features {
2461 let mut features = SupportedFeatures::new();
2462 self.inner.get_features(&mut features);
2463 map_features_to_wgpu(&features)
2464 }
2465
2466 fn limits(&self) -> wgpu::Limits {
2467 let mut limits = Limits::new();
2468 let _ = self.inner.get_limits(&mut limits);
2469 map_limits_to_wgpu(&limits)
2470 }
2471
2472 fn downlevel_capabilities(&self) -> wgpu::DownlevelCapabilities {
2473 wgpu::DownlevelCapabilities::default()
2474 }
2475
2476 fn get_info(&self) -> wgpu::AdapterInfo {
2477 let mut info = AdapterInfo::new();
2478 let _ = self.inner.get_info(&mut info);
2479 wgpu::AdapterInfo {
2480 name: info.description.clone().unwrap_or_default(),
2481 vendor: info.vendor_id.unwrap_or(0),
2482 device: info.device_id.unwrap_or(0),
2483 device_type: match info.adapter_type.unwrap_or(AdapterType::Unknown) {
2484 AdapterType::DiscreteGpu => wgpu::DeviceType::DiscreteGpu,
2485 AdapterType::IntegratedGpu => wgpu::DeviceType::IntegratedGpu,
2486 AdapterType::Cpu => wgpu::DeviceType::Cpu,
2487 AdapterType::Unknown => wgpu::DeviceType::Other,
2488 },
2489 backend: map_backend_type_to_wgpu(info.backend_type.unwrap_or(BackendType::Undefined)),
2490 driver: info.architecture.clone().unwrap_or_default(),
2491 driver_info: info.device.clone().unwrap_or_default(),
2492 device_pci_bus_id: String::new(),
2493 subgroup_min_size: wgpu::MINIMUM_SUBGROUP_MIN_SIZE,
2494 subgroup_max_size: wgpu::MAXIMUM_SUBGROUP_MAX_SIZE,
2495 transient_saves_memory: false,
2496 }
2497 }
2498
2499 fn get_texture_format_features(
2500 &self,
2501 _format: wgpu::TextureFormat,
2502 ) -> wgpu::TextureFormatFeatures {
2503 wgpu::TextureFormatFeatures {
2504 allowed_usages: wgpu::TextureUsages::empty(),
2505 flags: wgpu::TextureFormatFeatureFlags::empty(),
2506 }
2507 }
2508
2509 fn get_presentation_timestamp(&self) -> wgpu::PresentationTimestamp {
2510 wgpu::PresentationTimestamp::INVALID_TIMESTAMP
2511 }
2512}
2513
2514impl DeviceInterface for DawnDevice {
2515 fn features(&self) -> wgpu::Features {
2516 let adapter = self.inner.get_adapter();
2517 DawnAdapter { inner: adapter }.features()
2518 }
2519
2520 fn limits(&self) -> wgpu::Limits {
2521 let adapter = self.inner.get_adapter();
2522 DawnAdapter { inner: adapter }.limits()
2523 }
2524
2525 fn create_shader_module(
2526 &self,
2527 desc: wgpu::ShaderModuleDescriptor<'_>,
2528 _shader_bound_checks: wgpu::ShaderRuntimeChecks,
2529 ) -> DispatchShaderModule {
2530 let dawn_desc = map_shader_module_descriptor(desc);
2531 let module = self.inner.create_shader_module(&dawn_desc);
2532 dispatch_shader_module(module)
2533 }
2534
2535 unsafe fn create_shader_module_passthrough(
2536 &self,
2537 _desc: &wgpu::ShaderModuleDescriptorPassthrough<'_>,
2538 ) -> DispatchShaderModule {
2539 panic!("wgpu-compat: create_shader_module_passthrough not supported");
2540 }
2541
2542 fn create_bind_group_layout(
2543 &self,
2544 desc: &wgpu::BindGroupLayoutDescriptor<'_>,
2545 ) -> DispatchBindGroupLayout {
2546 let dawn_desc = map_bind_group_layout_descriptor(desc);
2547 let layout = self.inner.create_bind_group_layout(&dawn_desc);
2548 dispatch_bind_group_layout(layout)
2549 }
2550
2551 fn create_bind_group(&self, desc: &wgpu::BindGroupDescriptor<'_>) -> DispatchBindGroup {
2552 let dawn_desc = map_bind_group_descriptor(desc);
2553 let group = self.inner.create_bind_group(&dawn_desc);
2554 dispatch_bind_group(group)
2555 }
2556
2557 fn create_pipeline_layout(
2558 &self,
2559 desc: &wgpu::PipelineLayoutDescriptor<'_>,
2560 ) -> DispatchPipelineLayout {
2561 let dawn_desc = map_pipeline_layout_descriptor(desc);
2562 let layout = self.inner.create_pipeline_layout(&dawn_desc);
2563 dispatch_pipeline_layout(layout)
2564 }
2565
2566 fn create_render_pipeline(
2567 &self,
2568 desc: &wgpu::RenderPipelineDescriptor<'_>,
2569 ) -> DispatchRenderPipeline {
2570 let dawn_desc = map_render_pipeline_descriptor(desc);
2571 let pipeline = self.inner.create_render_pipeline(&dawn_desc);
2572 dispatch_render_pipeline(pipeline)
2573 }
2574
2575 fn create_mesh_pipeline(
2576 &self,
2577 _desc: &wgpu::MeshPipelineDescriptor<'_>,
2578 ) -> DispatchRenderPipeline {
2579 panic!("wgpu-compat: mesh pipelines not supported");
2580 }
2581
2582 fn create_compute_pipeline(
2583 &self,
2584 desc: &wgpu::ComputePipelineDescriptor<'_>,
2585 ) -> DispatchComputePipeline {
2586 let dawn_desc = map_compute_pipeline_descriptor(desc);
2587 let pipeline = self.inner.create_compute_pipeline(&dawn_desc);
2588 dispatch_compute_pipeline(pipeline)
2589 }
2590
2591 unsafe fn create_pipeline_cache(
2592 &self,
2593 _desc: &wgpu::PipelineCacheDescriptor<'_>,
2594 ) -> DispatchPipelineCache {
2595 dispatch_pipeline_cache()
2596 }
2597
2598 fn create_buffer(&self, desc: &wgpu::BufferDescriptor<'_>) -> DispatchBuffer {
2599 let dawn_desc = map_buffer_descriptor(desc);
2600 let buffer = self
2601 .inner
2602 .create_buffer(&dawn_desc)
2603 .expect("wgpu-compat: create_buffer returned null");
2604 dispatch_buffer(buffer)
2605 }
2606
2607 fn create_texture(&self, desc: &wgpu::TextureDescriptor<'_>) -> DispatchTexture {
2608 let dawn_desc = map_texture_descriptor(desc);
2609 let texture = self.inner.create_texture(&dawn_desc);
2610 dispatch_texture(texture)
2611 }
2612
2613 fn create_external_texture(
2614 &self,
2615 desc: &wgpu::ExternalTextureDescriptor<'_>,
2616 _planes: &[&wgpu::TextureView],
2617 ) -> DispatchExternalTexture {
2618 let mut dawn_desc = ExternalTextureDescriptor::new();
2619 dawn_desc.label = label_to_string(desc.label);
2620 let texture = self.inner.create_external_texture(&dawn_desc);
2621 dispatch_external_texture(texture)
2622 }
2623
2624 fn create_blas(
2625 &self,
2626 _desc: &wgpu::CreateBlasDescriptor<'_>,
2627 _sizes: wgpu::BlasGeometrySizeDescriptors,
2628 ) -> (Option<u64>, DispatchBlas) {
2629 (None, dispatch_blas())
2630 }
2631
2632 fn create_tlas(&self, _desc: &wgpu::CreateTlasDescriptor<'_>) -> DispatchTlas {
2633 dispatch_tlas()
2634 }
2635
2636 fn create_sampler(&self, desc: &wgpu::SamplerDescriptor<'_>) -> DispatchSampler {
2637 let dawn_desc = map_sampler_descriptor(desc);
2638 let sampler = self.inner.create_sampler(Some(&dawn_desc));
2639 dispatch_sampler(sampler)
2640 }
2641
2642 fn create_query_set(&self, desc: &wgpu::QuerySetDescriptor<'_>) -> DispatchQuerySet {
2643 let ty = match desc.ty {
2644 wgpu::QueryType::Occlusion => QueryType::Occlusion,
2645 wgpu::QueryType::Timestamp => QueryType::Timestamp,
2646 _ => panic!("wgpu-compat: query type not supported"),
2647 };
2648 let mut dawn_desc = QuerySetDescriptor::new();
2649 dawn_desc.label = label_to_string(desc.label);
2650 dawn_desc.r#type = Some(ty);
2651 dawn_desc.count = Some(desc.count);
2652 let set = self.inner.create_query_set(&dawn_desc);
2653 dispatch_query_set(set)
2654 }
2655
2656 fn create_command_encoder(
2657 &self,
2658 desc: &wgpu::CommandEncoderDescriptor<'_>,
2659 ) -> DispatchCommandEncoder {
2660 let dawn_desc = map_command_encoder_descriptor(desc);
2661 let encoder = self.inner.create_command_encoder(Some(&dawn_desc));
2662 dispatch_command_encoder(encoder)
2663 }
2664
2665 fn create_render_bundle_encoder(
2666 &self,
2667 desc: &wgpu::RenderBundleEncoderDescriptor<'_>,
2668 ) -> DispatchRenderBundleEncoder {
2669 let dawn_desc = map_render_bundle_encoder_descriptor(desc);
2670 let encoder = self.inner.create_render_bundle_encoder(&dawn_desc);
2671 dispatch_render_bundle_encoder(encoder)
2672 }
2673
2674 fn set_device_lost_callback(&self, _device_lost_callback: wgpu::custom::BoxDeviceLostCallback) {
2675 }
2676
2677 fn on_uncaptured_error(&self, _handler: Arc<dyn wgpu::UncapturedErrorHandler>) {}
2678
2679 fn push_error_scope(&self, filter: wgpu::ErrorFilter) -> u32 {
2680 let filter = match filter {
2681 wgpu::ErrorFilter::Validation => ErrorFilter::Validation,
2682 wgpu::ErrorFilter::OutOfMemory => ErrorFilter::OutOfMemory,
2683 wgpu::ErrorFilter::Internal => ErrorFilter::Internal,
2684 };
2685 self.inner.push_error_scope(filter);
2686 0
2687 }
2688
2689 fn pop_error_scope(&self, _index: u32) -> Pin<Box<dyn wgpu::custom::PopErrorScopeFuture>> {
2690 let (future, shared) = CallbackFuture::new();
2691 let _ = self.inner.pop_error_scope(move |status, ty, message| {
2692 if status == PopErrorScopeStatus::Success {
2693 if ty == ErrorType::NoError {
2694 complete_shared(&shared, None);
2695 } else {
2696 complete_shared(&shared, Some(map_uncaptured_error(ty, message)));
2697 }
2698 } else {
2699 complete_shared(
2700 &shared,
2701 Some(wgpu::Error::Internal {
2702 source: Box::new(DawnError("pop_error_scope failed".to_string())),
2703 description: "pop_error_scope failed".to_string(),
2704 }),
2705 );
2706 }
2707 });
2708 Box::pin(future)
2709 }
2710
2711 unsafe fn start_graphics_debugger_capture(&self) {
2712 let _ = &self.inner;
2713 }
2714
2715 unsafe fn stop_graphics_debugger_capture(&self) {
2716 let _ = &self.inner;
2717 }
2718
2719 fn poll(&self, _poll_type: wgt::PollType<u64>) -> Result<wgpu::PollStatus, wgpu::PollError> {
2720 self.inner.tick();
2721 Ok(wgpu::PollStatus::QueueEmpty)
2722 }
2723
2724 fn get_internal_counters(&self) -> wgpu::InternalCounters {
2725 wgpu::InternalCounters::default()
2726 }
2727
2728 fn generate_allocator_report(&self) -> Option<wgpu::AllocatorReport> {
2729 None
2730 }
2731
2732 fn destroy(&self) {
2733 self.inner.destroy();
2734 }
2735}
2736
2737impl QueueInterface for DawnQueue {
2738 fn write_buffer(&self, buffer: &DispatchBuffer, offset: wgpu::BufferAddress, data: &[u8]) {
2739 let buffer = expect_buffer(buffer);
2740 let data_ptr = data.as_ptr().cast::<std::ffi::c_void>();
2741 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, data.len()) };
2742 self.inner.write_buffer(buffer, offset, data_slice);
2743 }
2744
2745 fn create_staging_buffer(&self, size: wgpu::BufferSize) -> Option<DispatchQueueWriteBuffer> {
2746 Some(dispatch_queue_write_buffer(vec![0; size.get() as usize]))
2747 }
2748
2749 fn validate_write_buffer(
2750 &self,
2751 _buffer: &DispatchBuffer,
2752 _offset: wgpu::BufferAddress,
2753 _size: wgpu::BufferSize,
2754 ) -> Option<()> {
2755 Some(())
2756 }
2757
2758 fn write_staging_buffer(
2759 &self,
2760 buffer: &DispatchBuffer,
2761 offset: wgpu::BufferAddress,
2762 staging_buffer: &DispatchQueueWriteBuffer,
2763 ) {
2764 let buffer = expect_buffer(buffer);
2765 let staging = staging_buffer
2766 .as_custom::<DawnQueueWriteBuffer>()
2767 .expect("wgpu-compat: queue write buffer not dawn");
2768 let data_ptr = staging.inner.as_ptr().cast::<std::ffi::c_void>();
2769 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, staging.inner.len()) };
2770 self.inner.write_buffer(buffer, offset, data_slice);
2771 }
2772
2773 fn write_texture(
2774 &self,
2775 texture: wgpu::TexelCopyTextureInfo<'_>,
2776 data: &[u8],
2777 mut data_layout: wgpu::TexelCopyBufferLayout,
2778 size: wgpu::Extent3d,
2779 ) {
2780 if data_layout.rows_per_image.is_none()
2781 && (size.height > 1 || size.depth_or_array_layers > 1)
2782 {
2783 data_layout.rows_per_image = Some(size.height.max(1));
2784 }
2785 let destination = map_texel_copy_texture_info(texture);
2786 let data_layout = map_texel_copy_buffer_layout(data_layout);
2787 let write_size = map_extent_3d(size);
2788 let data_ptr = data.as_ptr().cast::<std::ffi::c_void>();
2789 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, data.len()) };
2790 self.inner
2791 .write_texture(&destination, data_slice, &data_layout, &write_size);
2792 }
2793
2794 #[cfg(web)]
2795 #[allow(unexpected_cfgs)]
2796 fn copy_external_image_to_texture(
2797 &self,
2798 _source: &wgpu::CopyExternalImageSourceInfo,
2799 _dest: wgpu::CopyExternalImageDestInfo<&wgpu::Texture>,
2800 _size: wgpu::Extent3d,
2801 ) {
2802 unimplemented!();
2803 }
2804
2805 fn submit(&self, command_buffers: &mut dyn Iterator<Item = DispatchCommandBuffer>) -> u64 {
2806 let buffers = command_buffers
2807 .map(|buffer| expect_command_buffer(&buffer))
2808 .collect::<Vec<_>>();
2809 self.inner.submit(&buffers);
2810 0
2811 }
2812
2813 fn get_timestamp_period(&self) -> f32 {
2814 1.0
2815 }
2816
2817 fn on_submitted_work_done(&self, callback: wgpu::custom::BoxSubmittedWorkDoneCallback) {
2818 let mut callback = Some(callback);
2819 let _ = self.inner.on_submitted_work_done(move |status, _message| {
2820 let _ = status;
2821 if let Some(cb) = callback.take() {
2822 cb();
2823 }
2824 });
2825 }
2826
2827 fn compact_blas(&self, _blas: &DispatchBlas) -> (Option<u64>, DispatchBlas) {
2828 (None, dispatch_blas())
2829 }
2830}
2831
2832impl ShaderModuleInterface for DawnShaderModule {
2833 fn get_compilation_info(&self) -> Pin<Box<dyn wgpu::custom::ShaderCompilationInfoFuture>> {
2834 let (future, shared) = CallbackFuture::new();
2835 let _ = self.inner.get_compilation_info(move |status, info| {
2836 if status == CompilationInfoRequestStatus::Success {
2837 complete_shared(&shared, map_compilation_info(info));
2838 } else {
2839 complete_shared(&shared, wgpu::CompilationInfo { messages: vec![] });
2840 }
2841 });
2842 Box::pin(future)
2843 }
2844}
2845
2846impl BindGroupLayoutInterface for DawnBindGroupLayout {}
2847impl BindGroupInterface for DawnBindGroup {}
2848impl TextureViewInterface for DawnTextureView {}
2849impl SamplerInterface for DawnSampler {}
2850
2851impl BufferInterface for DawnBuffer {
2852 fn map_async(
2853 &self,
2854 mode: wgpu::MapMode,
2855 range: std::ops::Range<wgpu::BufferAddress>,
2856 callback: wgpu::custom::BufferMapCallback,
2857 ) {
2858 let mode = match mode {
2859 wgpu::MapMode::Read => MapMode::READ,
2860 wgpu::MapMode::Write => MapMode::WRITE,
2861 };
2862 let mut callback = Some(callback);
2863 let _ = self.inner.map_async(
2864 mode,
2865 range.start as usize,
2866 (range.end - range.start) as usize,
2867 move |status, message| {
2868 let result = match status {
2869 MapAsyncStatus::Success => Ok(()),
2870 _ => {
2871 let _ = message;
2872 Err(wgpu::BufferAsyncError)
2873 }
2874 };
2875 if let Some(cb) = callback.take() {
2876 cb(result);
2877 }
2878 },
2879 );
2880 }
2881
2882 fn get_mapped_range(
2883 &self,
2884 sub_range: std::ops::Range<wgpu::BufferAddress>,
2885 ) -> DispatchBufferMappedRange {
2886 let ptr = self.inner.get_mapped_range(
2887 sub_range.start as usize,
2888 (sub_range.end - sub_range.start) as usize,
2889 );
2890 dispatch_buffer_mapped_range(ptr.cast(), (sub_range.end - sub_range.start) as usize)
2891 }
2892
2893 fn unmap(&self) {
2894 self.inner.unmap();
2895 }
2896
2897 fn destroy(&self) {
2898 self.inner.destroy();
2899 }
2900}
2901
2902impl TextureInterface for DawnTexture {
2903 fn create_view(&self, desc: &wgpu::TextureViewDescriptor<'_>) -> DispatchTextureView {
2904 let desc = map_texture_view_descriptor(desc);
2905 let view = self.inner.create_view(Some(&desc));
2906 dispatch_texture_view(view)
2907 }
2908
2909 fn destroy(&self) {
2910 self.inner.destroy();
2911 }
2912}
2913
2914impl ExternalTextureInterface for DawnExternalTexture {
2915 fn destroy(&self) {
2916 self.inner.destroy();
2917 }
2918}
2919
2920impl BlasInterface for DawnBlas {
2921 fn prepare_compact_async(&self, _callback: wgpu::custom::BlasCompactCallback) {
2922 panic!("wgpu-compat: blas not supported");
2923 }
2924
2925 fn ready_for_compaction(&self) -> bool {
2926 false
2927 }
2928}
2929
2930impl TlasInterface for DawnTlas {}
2931impl QuerySetInterface for DawnQuerySet {}
2932impl PipelineLayoutInterface for DawnPipelineLayout {}
2933
2934impl RenderPipelineInterface for DawnRenderPipeline {
2935 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout {
2936 let layout = self.inner.get_bind_group_layout(index);
2937 dispatch_bind_group_layout(layout)
2938 }
2939}
2940
2941impl ComputePipelineInterface for DawnComputePipeline {
2942 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout {
2943 let layout = self.inner.get_bind_group_layout(index);
2944 dispatch_bind_group_layout(layout)
2945 }
2946}
2947
2948impl PipelineCacheInterface for DawnPipelineCache {
2949 fn get_data(&self) -> Option<Vec<u8>> {
2950 None
2951 }
2952}
2953
2954impl CommandEncoderInterface for DawnCommandEncoder {
2955 fn copy_buffer_to_buffer(
2956 &self,
2957 source: &DispatchBuffer,
2958 source_offset: wgpu::BufferAddress,
2959 destination: &DispatchBuffer,
2960 destination_offset: wgpu::BufferAddress,
2961 copy_size: Option<wgpu::BufferAddress>,
2962 ) {
2963 let source = expect_buffer(source);
2964 let destination = expect_buffer(destination);
2965 self.inner.copy_buffer_to_buffer(
2966 source,
2967 source_offset,
2968 destination,
2969 destination_offset,
2970 copy_size.unwrap_or(WHOLE_SIZE),
2971 );
2972 }
2973
2974 fn copy_buffer_to_texture(
2975 &self,
2976 source: wgpu::TexelCopyBufferInfo<'_>,
2977 destination: wgpu::TexelCopyTextureInfo<'_>,
2978 copy_size: wgpu::Extent3d,
2979 ) {
2980 let source = map_texel_copy_buffer_info(source);
2981 let dest = map_texel_copy_texture_info(destination);
2982 let size = map_extent_3d(copy_size);
2983 self.inner.copy_buffer_to_texture(&source, &dest, &size);
2984 }
2985
2986 fn copy_texture_to_buffer(
2987 &self,
2988 source: wgpu::TexelCopyTextureInfo<'_>,
2989 destination: wgpu::TexelCopyBufferInfo<'_>,
2990 copy_size: wgpu::Extent3d,
2991 ) {
2992 let source = map_texel_copy_texture_info(source);
2993 let dest = map_texel_copy_buffer_info(destination);
2994 let size = map_extent_3d(copy_size);
2995 self.inner.copy_texture_to_buffer(&source, &dest, &size);
2996 }
2997
2998 fn copy_texture_to_texture(
2999 &self,
3000 source: wgpu::TexelCopyTextureInfo<'_>,
3001 destination: wgpu::TexelCopyTextureInfo<'_>,
3002 copy_size: wgpu::Extent3d,
3003 ) {
3004 let source = map_texel_copy_texture_info(source);
3005 let dest = map_texel_copy_texture_info(destination);
3006 let size = map_extent_3d(copy_size);
3007 self.inner.copy_texture_to_texture(&source, &dest, &size);
3008 }
3009
3010 fn begin_compute_pass(&self, desc: &wgpu::ComputePassDescriptor<'_>) -> DispatchComputePass {
3011 let dawn_desc = map_compute_pass_descriptor(desc);
3012 let pass = self.inner.begin_compute_pass(Some(&dawn_desc));
3013 dispatch_compute_pass(pass)
3014 }
3015
3016 fn begin_render_pass(&self, desc: &wgpu::RenderPassDescriptor<'_>) -> DispatchRenderPass {
3017 let dawn_desc = map_render_pass_descriptor(desc);
3018 let pass = self.inner.begin_render_pass(&dawn_desc);
3019 dispatch_render_pass(pass)
3020 }
3021
3022 fn finish(&mut self) -> DispatchCommandBuffer {
3023 let buffer = self.inner.finish(None);
3024 dispatch_command_buffer(buffer)
3025 }
3026
3027 fn clear_texture(
3028 &self,
3029 texture: &DispatchTexture,
3030 subresource_range: &wgpu::ImageSubresourceRange,
3031 ) {
3032 let _ = texture;
3033 let _ = subresource_range;
3034 }
3035
3036 fn clear_buffer(
3037 &self,
3038 buffer: &DispatchBuffer,
3039 offset: wgpu::BufferAddress,
3040 size: Option<wgpu::BufferAddress>,
3041 ) {
3042 let buffer = expect_buffer(buffer);
3043 self.inner
3044 .clear_buffer(buffer, offset, size.unwrap_or(WHOLE_SIZE));
3045 }
3046
3047 fn insert_debug_marker(&self, label: &str) {
3048 self.inner.insert_debug_marker(label.to_string());
3049 }
3050
3051 fn push_debug_group(&self, label: &str) {
3052 self.inner.push_debug_group(label.to_string());
3053 }
3054
3055 fn pop_debug_group(&self) {
3056 self.inner.pop_debug_group();
3057 }
3058
3059 fn write_timestamp(&self, query_set: &DispatchQuerySet, query_index: u32) {
3060 let set = expect_query_set(query_set);
3061 self.inner.write_timestamp(set, query_index);
3062 }
3063
3064 fn resolve_query_set(
3065 &self,
3066 query_set: &DispatchQuerySet,
3067 first_query: u32,
3068 query_count: u32,
3069 destination: &DispatchBuffer,
3070 destination_offset: wgpu::BufferAddress,
3071 ) {
3072 let set = expect_query_set(query_set);
3073 let buffer = expect_buffer(destination);
3074 self.inner
3075 .resolve_query_set(set, first_query, query_count, buffer, destination_offset);
3076 }
3077
3078 fn mark_acceleration_structures_built<'a>(
3079 &self,
3080 _blas: &mut dyn Iterator<Item = &'a wgpu::Blas>,
3081 _tlas: &mut dyn Iterator<Item = &'a wgpu::Tlas>,
3082 ) {
3083 panic!("wgpu-compat: blas/tlas not supported");
3084 }
3085
3086 fn build_acceleration_structures<'a>(
3087 &self,
3088 _blas: &mut dyn Iterator<Item = &'a wgpu::BlasBuildEntry<'a>>,
3089 _tlas: &mut dyn Iterator<Item = &'a wgpu::Tlas>,
3090 ) {
3091 panic!("wgpu-compat: blas/tlas not supported");
3092 }
3093
3094 fn transition_resources<'a>(
3095 &mut self,
3096 _buffer_transitions: &mut dyn Iterator<Item = wgpu::BufferTransition<&'a DispatchBuffer>>,
3097 _texture_transitions: &mut dyn Iterator<
3098 Item = wgpu::TextureTransition<&'a DispatchTexture>,
3099 >,
3100 ) {
3101 }
3102}
3103
3104impl ComputePassInterface for DawnComputePass {
3105 fn set_pipeline(&mut self, pipeline: &DispatchComputePipeline) {
3106 let pipeline = expect_compute_pipeline(pipeline);
3107 self.inner.set_pipeline(pipeline);
3108 }
3109
3110 fn set_bind_group(
3111 &mut self,
3112 index: u32,
3113 bind_group: Option<&DispatchBindGroup>,
3114 offsets: &[wgpu::DynamicOffset],
3115 ) {
3116 let group = bind_group.map(expect_bind_group);
3117 self.inner.set_bind_group(index, group, offsets);
3118 }
3119
3120 fn set_immediates(&mut self, offset: u32, data: &[u8]) {
3121 let data = bytes_to_u32(data);
3122 let data_ptr = data.as_ptr().cast::<std::ffi::c_void>();
3123 let data_len = data.len() * std::mem::size_of::<u32>();
3124 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, data_len) };
3125 self.inner.set_immediates(offset, data_slice);
3126 }
3127
3128 fn insert_debug_marker(&mut self, label: &str) {
3129 self.inner.insert_debug_marker(label.to_string());
3130 }
3131
3132 fn push_debug_group(&mut self, group_label: &str) {
3133 self.inner.push_debug_group(group_label.to_string());
3134 }
3135
3136 fn pop_debug_group(&mut self) {
3137 self.inner.pop_debug_group();
3138 }
3139
3140 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32) {
3141 let set = expect_query_set(query_set);
3142 self.inner.write_timestamp(set, query_index);
3143 }
3144
3145 fn begin_pipeline_statistics_query(
3146 &mut self,
3147 _query_set: &DispatchQuerySet,
3148 _query_index: u32,
3149 ) {
3150 panic!("wgpu-compat: pipeline statistics not supported");
3151 }
3152
3153 fn end_pipeline_statistics_query(&mut self) {
3154 panic!("wgpu-compat: pipeline statistics not supported");
3155 }
3156
3157 fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32) {
3158 self.inner.dispatch_workgroups(x, y, z);
3159 }
3160
3161 fn dispatch_workgroups_indirect(
3162 &mut self,
3163 indirect_buffer: &DispatchBuffer,
3164 indirect_offset: wgpu::BufferAddress,
3165 ) {
3166 let buffer = expect_buffer(indirect_buffer);
3167 self.inner
3168 .dispatch_workgroups_indirect(buffer, indirect_offset);
3169 }
3170
3171 fn end(&mut self) {
3172 if !self.ended {
3173 self.inner.end();
3174 self.ended = true;
3175 }
3176 }
3177}
3178
3179impl Drop for DawnComputePass {
3180 fn drop(&mut self) {
3181 if !self.ended {
3182 self.inner.end();
3183 self.ended = true;
3184 }
3185 }
3186}
3187
3188impl RenderPassInterface for DawnRenderPass {
3189 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline) {
3190 let pipeline = expect_render_pipeline(pipeline);
3191 self.inner.set_pipeline(pipeline);
3192 }
3193
3194 fn set_bind_group(
3195 &mut self,
3196 index: u32,
3197 bind_group: Option<&DispatchBindGroup>,
3198 offsets: &[wgpu::DynamicOffset],
3199 ) {
3200 let group = bind_group.map(expect_bind_group);
3201 self.inner.set_bind_group(index, group, offsets);
3202 }
3203
3204 fn set_index_buffer(
3205 &mut self,
3206 buffer: &DispatchBuffer,
3207 index_format: wgpu::IndexFormat,
3208 offset: wgpu::BufferAddress,
3209 size: Option<wgpu::BufferSize>,
3210 ) {
3211 let buffer = expect_buffer(buffer);
3212 let size = size.map(|v| v.get()).unwrap_or(WHOLE_SIZE);
3213 self.inner
3214 .set_index_buffer(buffer, map_index_format(index_format), offset, size);
3215 }
3216
3217 fn set_vertex_buffer(
3218 &mut self,
3219 slot: u32,
3220 buffer: &DispatchBuffer,
3221 offset: wgpu::BufferAddress,
3222 size: Option<wgpu::BufferSize>,
3223 ) {
3224 let buffer = expect_buffer(buffer);
3225 let size = size.map(|v| v.get()).unwrap_or(WHOLE_SIZE);
3226 self.inner
3227 .set_vertex_buffer(slot, Some(buffer), offset, size);
3228 }
3229
3230 fn set_immediates(&mut self, offset: u32, data: &[u8]) {
3231 let data = bytes_to_u32(data);
3232 let data_ptr = data.as_ptr().cast::<std::ffi::c_void>();
3233 let data_len = data.len() * std::mem::size_of::<u32>();
3234 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, data_len) };
3235 self.inner.set_immediates(offset, data_slice);
3236 }
3237
3238 fn set_blend_constant(&mut self, color: wgpu::Color) {
3239 let color = map_color(color);
3240 self.inner.set_blend_constant(&color);
3241 }
3242
3243 fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32) {
3244 self.inner.set_scissor_rect(x, y, width, height);
3245 }
3246
3247 fn set_viewport(
3248 &mut self,
3249 x: f32,
3250 y: f32,
3251 width: f32,
3252 height: f32,
3253 min_depth: f32,
3254 max_depth: f32,
3255 ) {
3256 self.inner
3257 .set_viewport(x, y, width, height, min_depth, max_depth);
3258 }
3259
3260 fn set_stencil_reference(&mut self, reference: u32) {
3261 self.inner.set_stencil_reference(reference);
3262 }
3263
3264 fn draw(&mut self, vertices: std::ops::Range<u32>, instances: std::ops::Range<u32>) {
3265 self.inner.draw(
3266 vertices.end - vertices.start,
3267 instances.end - instances.start,
3268 vertices.start,
3269 instances.start,
3270 );
3271 }
3272
3273 fn draw_indexed(
3274 &mut self,
3275 indices: std::ops::Range<u32>,
3276 base_vertex: i32,
3277 instances: std::ops::Range<u32>,
3278 ) {
3279 self.inner.draw_indexed(
3280 indices.end - indices.start,
3281 instances.end - instances.start,
3282 indices.start,
3283 base_vertex,
3284 instances.start,
3285 );
3286 }
3287
3288 fn draw_mesh_tasks(&mut self, _group_count_x: u32, _group_count_y: u32, _group_count_z: u32) {
3289 panic!("wgpu-compat: mesh tasks not supported");
3290 }
3291
3292 fn draw_indirect(
3293 &mut self,
3294 indirect_buffer: &DispatchBuffer,
3295 indirect_offset: wgpu::BufferAddress,
3296 ) {
3297 let buffer = expect_buffer(indirect_buffer);
3298 self.inner.draw_indirect(buffer, indirect_offset);
3299 }
3300
3301 fn draw_indexed_indirect(
3302 &mut self,
3303 indirect_buffer: &DispatchBuffer,
3304 indirect_offset: wgpu::BufferAddress,
3305 ) {
3306 let buffer = expect_buffer(indirect_buffer);
3307 self.inner.draw_indexed_indirect(buffer, indirect_offset);
3308 }
3309
3310 fn draw_mesh_tasks_indirect(
3311 &mut self,
3312 _indirect_buffer: &DispatchBuffer,
3313 _indirect_offset: wgpu::BufferAddress,
3314 ) {
3315 panic!("wgpu-compat: mesh tasks not supported");
3316 }
3317
3318 fn multi_draw_indirect(
3319 &mut self,
3320 indirect_buffer: &DispatchBuffer,
3321 indirect_offset: wgpu::BufferAddress,
3322 count: u32,
3323 ) {
3324 let buffer = expect_buffer(indirect_buffer);
3325 self.inner
3326 .multi_draw_indirect(buffer, indirect_offset, count, None, 0);
3327 }
3328
3329 fn multi_draw_indexed_indirect(
3330 &mut self,
3331 indirect_buffer: &DispatchBuffer,
3332 indirect_offset: wgpu::BufferAddress,
3333 count: u32,
3334 ) {
3335 let buffer = expect_buffer(indirect_buffer);
3336 self.inner
3337 .multi_draw_indexed_indirect(buffer, indirect_offset, count, None, 0);
3338 }
3339
3340 fn multi_draw_indirect_count(
3341 &mut self,
3342 _indirect_buffer: &DispatchBuffer,
3343 _indirect_offset: wgpu::BufferAddress,
3344 _count_buffer: &DispatchBuffer,
3345 _count_buffer_offset: wgpu::BufferAddress,
3346 _max_count: u32,
3347 ) {
3348 panic!("wgpu-compat: multi_draw_indirect_count not supported");
3349 }
3350
3351 fn multi_draw_mesh_tasks_indirect(
3352 &mut self,
3353 _indirect_buffer: &DispatchBuffer,
3354 _indirect_offset: wgpu::BufferAddress,
3355 _count: u32,
3356 ) {
3357 panic!("wgpu-compat: mesh tasks not supported");
3358 }
3359
3360 fn multi_draw_indexed_indirect_count(
3361 &mut self,
3362 _indirect_buffer: &DispatchBuffer,
3363 _indirect_offset: wgpu::BufferAddress,
3364 _count_buffer: &DispatchBuffer,
3365 _count_buffer_offset: wgpu::BufferAddress,
3366 _max_count: u32,
3367 ) {
3368 panic!("wgpu-compat: multi_draw_indexed_indirect_count not supported");
3369 }
3370
3371 fn multi_draw_mesh_tasks_indirect_count(
3372 &mut self,
3373 _indirect_buffer: &DispatchBuffer,
3374 _indirect_offset: wgpu::BufferAddress,
3375 _count_buffer: &DispatchBuffer,
3376 _count_buffer_offset: wgpu::BufferAddress,
3377 _max_count: u32,
3378 ) {
3379 panic!("wgpu-compat: mesh tasks not supported");
3380 }
3381
3382 fn insert_debug_marker(&mut self, label: &str) {
3383 self.inner.insert_debug_marker(label.to_string());
3384 }
3385
3386 fn push_debug_group(&mut self, group_label: &str) {
3387 self.inner.push_debug_group(group_label.to_string());
3388 }
3389
3390 fn pop_debug_group(&mut self) {
3391 self.inner.pop_debug_group();
3392 }
3393
3394 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32) {
3395 let set = expect_query_set(query_set);
3396 self.inner.write_timestamp(set, query_index);
3397 }
3398
3399 fn begin_occlusion_query(&mut self, query_index: u32) {
3400 self.inner.begin_occlusion_query(query_index);
3401 }
3402
3403 fn end_occlusion_query(&mut self) {
3404 self.inner.end_occlusion_query();
3405 }
3406
3407 fn begin_pipeline_statistics_query(
3408 &mut self,
3409 _query_set: &DispatchQuerySet,
3410 _query_index: u32,
3411 ) {
3412 panic!("wgpu-compat: pipeline statistics not supported");
3413 }
3414
3415 fn end_pipeline_statistics_query(&mut self) {
3416 panic!("wgpu-compat: pipeline statistics not supported");
3417 }
3418
3419 fn execute_bundles(&mut self, render_bundles: &mut dyn Iterator<Item = &DispatchRenderBundle>) {
3420 let bundles = render_bundles.map(expect_render_bundle).collect::<Vec<_>>();
3421 self.inner.execute_bundles(&bundles);
3422 }
3423
3424 fn end(&mut self) {
3425 if !self.ended {
3426 self.inner.end();
3427 self.ended = true;
3428 }
3429 }
3430}
3431
3432impl Drop for DawnRenderPass {
3433 fn drop(&mut self) {
3434 if !self.ended {
3435 self.inner.end();
3436 self.ended = true;
3437 }
3438 }
3439}
3440
3441impl RenderBundleEncoderInterface for DawnRenderBundleEncoder {
3442 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline) {
3443 let pipeline = expect_render_pipeline(pipeline);
3444 self.inner.set_pipeline(pipeline);
3445 }
3446
3447 fn set_bind_group(
3448 &mut self,
3449 index: u32,
3450 bind_group: Option<&DispatchBindGroup>,
3451 offsets: &[wgpu::DynamicOffset],
3452 ) {
3453 let group = bind_group.map(expect_bind_group);
3454 self.inner.set_bind_group(index, group, offsets);
3455 }
3456
3457 fn set_index_buffer(
3458 &mut self,
3459 buffer: &DispatchBuffer,
3460 index_format: wgpu::IndexFormat,
3461 offset: wgpu::BufferAddress,
3462 size: Option<wgpu::BufferSize>,
3463 ) {
3464 let buffer = expect_buffer(buffer);
3465 let size = size.map(|v| v.get()).unwrap_or(WHOLE_SIZE);
3466 self.inner
3467 .set_index_buffer(buffer, map_index_format(index_format), offset, size);
3468 }
3469
3470 fn set_vertex_buffer(
3471 &mut self,
3472 slot: u32,
3473 buffer: &DispatchBuffer,
3474 offset: wgpu::BufferAddress,
3475 size: Option<wgpu::BufferSize>,
3476 ) {
3477 let buffer = expect_buffer(buffer);
3478 let size = size.map(|v| v.get()).unwrap_or(WHOLE_SIZE);
3479 self.inner
3480 .set_vertex_buffer(slot, Some(buffer), offset, size);
3481 }
3482
3483 fn set_immediates(&mut self, offset: u32, data: &[u8]) {
3484 let data = bytes_to_u32(data);
3485 let data_ptr = data.as_ptr().cast::<std::ffi::c_void>();
3486 let data_len = data.len() * std::mem::size_of::<u32>();
3487 let data_slice = unsafe { std::slice::from_raw_parts(data_ptr, data_len) };
3488 self.inner.set_immediates(offset, data_slice);
3489 }
3490
3491 fn draw(&mut self, vertices: std::ops::Range<u32>, instances: std::ops::Range<u32>) {
3492 self.inner.draw(
3493 vertices.end - vertices.start,
3494 instances.end - instances.start,
3495 vertices.start,
3496 instances.start,
3497 );
3498 }
3499
3500 fn draw_indexed(
3501 &mut self,
3502 indices: std::ops::Range<u32>,
3503 base_vertex: i32,
3504 instances: std::ops::Range<u32>,
3505 ) {
3506 self.inner.draw_indexed(
3507 indices.end - indices.start,
3508 instances.end - instances.start,
3509 indices.start,
3510 base_vertex,
3511 instances.start,
3512 );
3513 }
3514
3515 fn draw_indirect(
3516 &mut self,
3517 indirect_buffer: &DispatchBuffer,
3518 indirect_offset: wgpu::BufferAddress,
3519 ) {
3520 let buffer = expect_buffer(indirect_buffer);
3521 self.inner.draw_indirect(buffer, indirect_offset);
3522 }
3523
3524 fn draw_indexed_indirect(
3525 &mut self,
3526 indirect_buffer: &DispatchBuffer,
3527 indirect_offset: wgpu::BufferAddress,
3528 ) {
3529 let buffer = expect_buffer(indirect_buffer);
3530 self.inner.draw_indexed_indirect(buffer, indirect_offset);
3531 }
3532
3533 fn finish(self, desc: &wgpu::RenderBundleDescriptor<'_>) -> DispatchRenderBundle {
3534 let mut dawn_desc = RenderBundleDescriptor::new();
3535 dawn_desc.label = label_to_string(desc.label);
3536 let bundle = self.inner.finish(Some(&dawn_desc));
3537 dispatch_render_bundle(bundle)
3538 }
3539}
3540
3541impl CommandBufferInterface for DawnCommandBuffer {}
3542impl RenderBundleInterface for DawnRenderBundle {}
3543
3544impl SurfaceInterface for DawnSurface {
3545 fn get_capabilities(&self, adapter: &DispatchAdapter) -> wgpu::SurfaceCapabilities {
3546 let adapter = expect_adapter(adapter);
3547 let mut caps = SurfaceCapabilities::new();
3548 let _ = self.inner.get_capabilities(adapter, &mut caps);
3549 map_surface_capabilities(caps)
3550 }
3551
3552 fn configure(&self, device: &DispatchDevice, config: &wgpu::SurfaceConfiguration) {
3553 let mut config = map_surface_configuration(config);
3554 config.device = Some(expect_device(device));
3555 self.inner.configure(&config);
3556 }
3557
3558 fn get_current_texture(
3559 &self,
3560 ) -> (
3561 Option<DispatchTexture>,
3562 wgpu::SurfaceStatus,
3563 DispatchSurfaceOutputDetail,
3564 ) {
3565 let mut surface_texture = SurfaceTexture::new();
3566 self.inner.get_current_texture(&mut surface_texture);
3567 let status = match surface_texture
3568 .status
3569 .unwrap_or(SurfaceGetCurrentTextureStatus::Error)
3570 {
3571 SurfaceGetCurrentTextureStatus::SuccessOptimal => wgpu::SurfaceStatus::Good,
3572 SurfaceGetCurrentTextureStatus::SuccessSuboptimal => wgpu::SurfaceStatus::Suboptimal,
3573 SurfaceGetCurrentTextureStatus::Timeout => wgpu::SurfaceStatus::Timeout,
3574 SurfaceGetCurrentTextureStatus::Outdated => wgpu::SurfaceStatus::Outdated,
3575 SurfaceGetCurrentTextureStatus::Lost => wgpu::SurfaceStatus::Lost,
3576 SurfaceGetCurrentTextureStatus::Error => wgpu::SurfaceStatus::Unknown,
3577 };
3578 (
3579 surface_texture.texture.map(dispatch_texture),
3580 status,
3581 dispatch_surface_output_detail(self.inner.clone()),
3582 )
3583 }
3584}
3585
3586impl SurfaceOutputDetailInterface for DawnSurfaceOutputDetail {
3587 fn present(&self) {
3588 let _ = self.surface.present();
3589 }
3590
3591 fn texture_discard(&self) {
3592 }
3594}
3595
3596impl QueueWriteBufferInterface for DawnQueueWriteBuffer {
3597 fn slice(&self) -> &[u8] {
3598 &self.inner
3599 }
3600
3601 fn slice_mut(&mut self) -> &mut [u8] {
3602 &mut self.inner
3603 }
3604}
3605
3606impl BufferMappedRangeInterface for DawnBufferMappedRange {
3607 fn slice(&self) -> &[u8] {
3608 if self.data.is_null() || self.size == 0 {
3609 return &[];
3610 }
3611 unsafe { std::slice::from_raw_parts(self.data, self.size) }
3612 }
3613
3614 fn slice_mut(&mut self) -> &mut [u8] {
3615 if self.data.is_null() || self.size == 0 {
3616 return &mut [];
3617 }
3618 unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
3619 }
3620
3621 #[cfg(web)]
3622 #[allow(unexpected_cfgs)]
3623 fn as_uint8array(&self) -> &js_sys::Uint8Array {
3624 unimplemented!();
3625 }
3626}
3627
3628pub fn to_wgpu_instance(instance: Instance) -> wgpu::Instance {
3629 wgpu::Instance::from_custom(DawnInstance { inner: instance })
3630}
3631
3632pub fn from_wgpu_instance(instance: &wgpu::Instance) -> Result<Instance, WgpuCompatError> {
3633 instance
3634 .as_custom::<DawnInstance>()
3635 .map(|i| i.inner.clone())
3636 .ok_or(WgpuCompatError::NotDawnBackend)
3637}
3638
3639pub fn to_wgpu_adapter(adapter: Adapter) -> wgpu::Adapter {
3640 wgpu::Adapter::from_custom(DawnAdapter { inner: adapter })
3641}
3642
3643pub fn from_wgpu_adapter(adapter: &wgpu::Adapter) -> Result<Adapter, WgpuCompatError> {
3644 adapter
3645 .as_custom::<DawnAdapter>()
3646 .map(|a| a.inner.clone())
3647 .ok_or(WgpuCompatError::NotDawnBackend)
3648}
3649
3650pub fn to_wgpu_device(device: Device) -> wgpu::Device {
3651 wgpu::Device::from_custom(DawnDevice { inner: device })
3652}
3653
3654pub fn from_wgpu_device(device: &wgpu::Device) -> Result<Device, WgpuCompatError> {
3655 device
3656 .as_custom::<DawnDevice>()
3657 .map(|d| d.inner.clone())
3658 .ok_or(WgpuCompatError::NotDawnBackend)
3659}
3660
3661pub fn to_wgpu_queue(queue: Queue) -> wgpu::Queue {
3662 wgpu::Queue::from_custom(DawnQueue { inner: queue })
3663}
3664
3665pub fn from_wgpu_queue(queue: &wgpu::Queue) -> Result<Queue, WgpuCompatError> {
3666 queue
3667 .as_custom::<DawnQueue>()
3668 .map(|q| q.inner.clone())
3669 .ok_or(WgpuCompatError::NotDawnBackend)
3670}
3671
3672pub fn from_wgpu_surface(surface: &wgpu::Surface) -> Result<Surface, WgpuCompatError> {
3673 surface
3674 .as_custom::<DawnSurface>()
3675 .map(|s| s.inner.clone())
3676 .ok_or(WgpuCompatError::NotDawnBackend)
3677}
3678
3679pub fn from_wgpu_buffer(buffer: &wgpu::Buffer) -> Result<Buffer, WgpuCompatError> {
3680 buffer
3681 .as_custom::<DawnBuffer>()
3682 .map(|b| b.inner.clone())
3683 .ok_or(WgpuCompatError::NotDawnBackend)
3684}
3685
3686pub fn to_wgpu_texture(texture: Texture, desc: &wgpu::TextureDescriptor<'_>) -> wgpu::Texture {
3687 wgpu::Texture::from_custom(DawnTexture { inner: texture }, desc)
3688}
3689
3690pub fn from_wgpu_texture(texture: &wgpu::Texture) -> Result<Texture, WgpuCompatError> {
3691 texture
3692 .as_custom::<DawnTexture>()
3693 .map(|t| t.inner.clone())
3694 .ok_or(WgpuCompatError::NotDawnBackend)
3695}
3696
3697pub fn from_wgpu_texture_view(view: &wgpu::TextureView) -> Result<TextureView, WgpuCompatError> {
3698 view.as_custom::<DawnTextureView>()
3699 .map(|v| v.inner.clone())
3700 .ok_or(WgpuCompatError::NotDawnBackend)
3701}
3702
3703pub fn from_wgpu_sampler(sampler: &wgpu::Sampler) -> Result<Sampler, WgpuCompatError> {
3704 sampler
3705 .as_custom::<DawnSampler>()
3706 .map(|s| s.inner.clone())
3707 .ok_or(WgpuCompatError::NotDawnBackend)
3708}
3709
3710pub fn from_wgpu_bind_group_layout(
3711 layout: &wgpu::BindGroupLayout,
3712) -> Result<BindGroupLayout, WgpuCompatError> {
3713 layout
3714 .as_custom::<DawnBindGroupLayout>()
3715 .map(|l| l.inner.clone())
3716 .ok_or(WgpuCompatError::NotDawnBackend)
3717}
3718
3719pub fn from_wgpu_bind_group(group: &wgpu::BindGroup) -> Result<BindGroup, WgpuCompatError> {
3720 group
3721 .as_custom::<DawnBindGroup>()
3722 .map(|g| g.inner.clone())
3723 .ok_or(WgpuCompatError::NotDawnBackend)
3724}
3725
3726pub fn from_wgpu_pipeline_layout(
3727 layout: &wgpu::PipelineLayout,
3728) -> Result<PipelineLayout, WgpuCompatError> {
3729 layout
3730 .as_custom::<DawnPipelineLayout>()
3731 .map(|l| l.inner.clone())
3732 .ok_or(WgpuCompatError::NotDawnBackend)
3733}
3734
3735pub fn from_wgpu_render_pipeline(
3736 pipeline: &wgpu::RenderPipeline,
3737) -> Result<RenderPipeline, WgpuCompatError> {
3738 pipeline
3739 .as_custom::<DawnRenderPipeline>()
3740 .map(|p| p.inner.clone())
3741 .ok_or(WgpuCompatError::NotDawnBackend)
3742}
3743
3744pub fn from_wgpu_compute_pipeline(
3745 pipeline: &wgpu::ComputePipeline,
3746) -> Result<ComputePipeline, WgpuCompatError> {
3747 pipeline
3748 .as_custom::<DawnComputePipeline>()
3749 .map(|p| p.inner.clone())
3750 .ok_or(WgpuCompatError::NotDawnBackend)
3751}
3752
3753pub fn from_wgpu_shader_module(
3754 module: &wgpu::ShaderModule,
3755) -> Result<ShaderModule, WgpuCompatError> {
3756 module
3757 .as_custom::<DawnShaderModule>()
3758 .map(|m| m.inner.clone())
3759 .ok_or(WgpuCompatError::NotDawnBackend)
3760}
3761
3762pub fn from_wgpu_command_encoder(
3763 encoder: &wgpu::CommandEncoder,
3764) -> Result<CommandEncoder, WgpuCompatError> {
3765 encoder
3766 .as_custom::<DawnCommandEncoder>()
3767 .map(|e| e.inner.clone())
3768 .ok_or(WgpuCompatError::NotDawnBackend)
3769}
3770
3771pub fn from_wgpu_command_buffer(
3772 buffer: &wgpu::CommandBuffer,
3773) -> Result<CommandBuffer, WgpuCompatError> {
3774 buffer
3775 .as_custom::<DawnCommandBuffer>()
3776 .map(|b| b.inner.clone())
3777 .ok_or(WgpuCompatError::NotDawnBackend)
3778}
3779
3780pub fn from_wgpu_render_bundle(
3781 bundle: &wgpu::RenderBundle,
3782) -> Result<RenderBundle, WgpuCompatError> {
3783 bundle
3784 .as_custom::<DawnRenderBundle>()
3785 .map(|b| b.inner.clone())
3786 .ok_or(WgpuCompatError::NotDawnBackend)
3787}
3788
3789pub fn from_wgpu_query_set(query_set: &wgpu::QuerySet) -> Result<QuerySet, WgpuCompatError> {
3790 query_set
3791 .as_custom::<DawnQuerySet>()
3792 .map(|q| q.inner.clone())
3793 .ok_or(WgpuCompatError::NotDawnBackend)
3794}