1#![allow(drop_bounds)] #![allow(clippy::too_many_arguments)] #![allow(missing_docs, clippy::missing_safety_doc)] use crate::{Blas, Tlas, WasmNotSend, WasmNotSendSync};
16
17use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
18use core::{any::Any, fmt::Debug, future::Future, hash::Hash, ops::Range, pin::Pin};
19
20#[cfg(custom)]
21use crate::backend::custom::*;
22#[cfg(webgpu)]
23use crate::backend::webgpu::*;
24#[cfg(wgpu_core)]
25use crate::backend::wgpu_core::*;
26
27macro_rules! trait_alias {
31 ($name:ident: $($bound:tt)+) => {
32 pub trait $name: $($bound)+ {}
33 impl<T: $($bound)+> $name for T {}
34 };
35}
36
37trait_alias!(RequestAdapterFuture: Future<Output = Result<DispatchAdapter, wgt::RequestAdapterError>> + WasmNotSend + 'static);
39trait_alias!(RequestDeviceFuture: Future<Output = Result<(DispatchDevice, DispatchQueue), crate::RequestDeviceError>> + WasmNotSend + 'static);
40trait_alias!(PopErrorScopeFuture: Future<Output = Option<crate::Error>> + WasmNotSend + 'static);
41trait_alias!(ShaderCompilationInfoFuture: Future<Output = crate::CompilationInfo> + WasmNotSend + 'static);
42
43#[cfg(send_sync)]
45pub type BoxDeviceLostCallback = Box<dyn FnOnce(crate::DeviceLostReason, String) + Send + 'static>;
46#[cfg(not(send_sync))]
47pub type BoxDeviceLostCallback = Box<dyn FnOnce(crate::DeviceLostReason, String) + 'static>;
48#[cfg(send_sync)]
49pub type BoxSubmittedWorkDoneCallback = Box<dyn FnOnce() + Send + 'static>;
50#[cfg(not(send_sync))]
51pub type BoxSubmittedWorkDoneCallback = Box<dyn FnOnce() + 'static>;
52#[cfg(send_sync)]
53pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + Send + 'static>;
54#[cfg(not(send_sync))]
55pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + 'static>;
56
57#[cfg(send_sync)]
58pub type BlasCompactCallback = Box<dyn FnOnce(Result<(), crate::BlasAsyncError>) + Send + 'static>;
59#[cfg(not(send_sync))]
60pub type BlasCompactCallback = Box<dyn FnOnce(Result<(), crate::BlasAsyncError>) + 'static>;
61
62#[cfg_attr(not(custom), expect(dead_code))]
64pub trait AsAny {
65 fn as_any(&self) -> &dyn Any;
66}
67
68impl<T: 'static> AsAny for T {
69 fn as_any(&self) -> &dyn Any {
70 self
71 }
72}
73
74trait_alias!(CommonTraits: AsAny + Any + Debug + WasmNotSendSync);
76
77pub trait InstanceInterface: CommonTraits {
78 fn new(desc: &crate::InstanceDescriptor) -> Self
79 where
80 Self: Sized;
81
82 unsafe fn create_surface(
83 &self,
84 target: crate::SurfaceTargetUnsafe,
85 ) -> Result<DispatchSurface, crate::CreateSurfaceError>;
86
87 fn request_adapter(
88 &self,
89 options: &crate::RequestAdapterOptions<'_, '_>,
90 ) -> Pin<Box<dyn RequestAdapterFuture>>;
91
92 fn poll_all_devices(&self, force_wait: bool) -> bool;
93
94 #[cfg(feature = "wgsl")]
95 fn wgsl_language_features(&self) -> crate::WgslLanguageFeatures;
96}
97
98pub trait AdapterInterface: CommonTraits {
99 fn request_device(
100 &self,
101 desc: &crate::DeviceDescriptor<'_>,
102 ) -> Pin<Box<dyn RequestDeviceFuture>>;
103
104 fn is_surface_supported(&self, surface: &DispatchSurface) -> bool;
105
106 fn features(&self) -> crate::Features;
107
108 fn limits(&self) -> crate::Limits;
109
110 fn downlevel_capabilities(&self) -> crate::DownlevelCapabilities;
111
112 fn get_info(&self) -> crate::AdapterInfo;
113
114 fn get_texture_format_features(
115 &self,
116 format: crate::TextureFormat,
117 ) -> crate::TextureFormatFeatures;
118
119 fn get_presentation_timestamp(&self) -> crate::PresentationTimestamp;
120}
121
122pub trait DeviceInterface: CommonTraits {
123 fn features(&self) -> crate::Features;
124 fn limits(&self) -> crate::Limits;
125
126 fn create_shader_module(
127 &self,
128 desc: crate::ShaderModuleDescriptor<'_>,
129 shader_bound_checks: crate::ShaderRuntimeChecks,
130 ) -> DispatchShaderModule;
131
132 unsafe fn create_shader_module_passthrough(
133 &self,
134 desc: &crate::ShaderModuleDescriptorPassthrough<'_>,
135 ) -> DispatchShaderModule;
136
137 fn create_bind_group_layout(
138 &self,
139 desc: &crate::BindGroupLayoutDescriptor<'_>,
140 ) -> DispatchBindGroupLayout;
141 fn create_bind_group(&self, desc: &crate::BindGroupDescriptor<'_>) -> DispatchBindGroup;
142 fn create_pipeline_layout(
143 &self,
144 desc: &crate::PipelineLayoutDescriptor<'_>,
145 ) -> DispatchPipelineLayout;
146 fn create_render_pipeline(
147 &self,
148 desc: &crate::RenderPipelineDescriptor<'_>,
149 ) -> DispatchRenderPipeline;
150 fn create_mesh_pipeline(
151 &self,
152 desc: &crate::MeshPipelineDescriptor<'_>,
153 ) -> DispatchRenderPipeline;
154 fn create_compute_pipeline(
155 &self,
156 desc: &crate::ComputePipelineDescriptor<'_>,
157 ) -> DispatchComputePipeline;
158 unsafe fn create_pipeline_cache(
159 &self,
160 desc: &crate::PipelineCacheDescriptor<'_>,
161 ) -> DispatchPipelineCache;
162 fn create_buffer(&self, desc: &crate::BufferDescriptor<'_>) -> DispatchBuffer;
163 fn create_texture(&self, desc: &crate::TextureDescriptor<'_>) -> DispatchTexture;
164 fn create_external_texture(
165 &self,
166 desc: &crate::ExternalTextureDescriptor<'_>,
167 planes: &[&crate::TextureView],
168 ) -> DispatchExternalTexture;
169 fn create_blas(
170 &self,
171 desc: &crate::CreateBlasDescriptor<'_>,
172 sizes: crate::BlasGeometrySizeDescriptors,
173 ) -> (Option<u64>, DispatchBlas);
174 fn create_tlas(&self, desc: &crate::CreateTlasDescriptor<'_>) -> DispatchTlas;
175 fn create_sampler(&self, desc: &crate::SamplerDescriptor<'_>) -> DispatchSampler;
176 fn create_query_set(&self, desc: &crate::QuerySetDescriptor<'_>) -> DispatchQuerySet;
177 fn create_command_encoder(
178 &self,
179 desc: &crate::CommandEncoderDescriptor<'_>,
180 ) -> DispatchCommandEncoder;
181 fn create_render_bundle_encoder(
182 &self,
183 desc: &crate::RenderBundleEncoderDescriptor<'_>,
184 ) -> DispatchRenderBundleEncoder;
185
186 fn set_device_lost_callback(&self, device_lost_callback: BoxDeviceLostCallback);
187
188 fn on_uncaptured_error(&self, handler: Arc<dyn crate::UncapturedErrorHandler>);
189 fn push_error_scope(&self, filter: crate::ErrorFilter);
190 fn pop_error_scope(&self) -> Pin<Box<dyn PopErrorScopeFuture>>;
191
192 unsafe fn start_graphics_debugger_capture(&self);
193 unsafe fn stop_graphics_debugger_capture(&self);
194
195 fn poll(&self, poll_type: wgt::PollType<u64>) -> Result<crate::PollStatus, crate::PollError>;
196
197 fn get_internal_counters(&self) -> crate::InternalCounters;
198 fn generate_allocator_report(&self) -> Option<crate::AllocatorReport>;
199
200 fn destroy(&self);
201}
202
203pub trait QueueInterface: CommonTraits {
204 fn write_buffer(&self, buffer: &DispatchBuffer, offset: crate::BufferAddress, data: &[u8]);
205
206 fn create_staging_buffer(&self, size: crate::BufferSize) -> Option<DispatchQueueWriteBuffer>;
207 fn validate_write_buffer(
208 &self,
209 buffer: &DispatchBuffer,
210 offset: crate::BufferAddress,
211 size: crate::BufferSize,
212 ) -> Option<()>;
213 fn write_staging_buffer(
214 &self,
215 buffer: &DispatchBuffer,
216 offset: crate::BufferAddress,
217 staging_buffer: &DispatchQueueWriteBuffer,
218 );
219
220 fn write_texture(
221 &self,
222 texture: crate::TexelCopyTextureInfo<'_>,
223 data: &[u8],
224 data_layout: crate::TexelCopyBufferLayout,
225 size: crate::Extent3d,
226 );
227 #[cfg(web)]
228 fn copy_external_image_to_texture(
229 &self,
230 source: &crate::CopyExternalImageSourceInfo,
231 dest: crate::CopyExternalImageDestInfo<&crate::api::Texture>,
232 size: crate::Extent3d,
233 );
234
235 fn submit(&self, command_buffers: &mut dyn Iterator<Item = DispatchCommandBuffer>) -> u64;
236
237 fn get_timestamp_period(&self) -> f32;
238 fn on_submitted_work_done(&self, callback: BoxSubmittedWorkDoneCallback);
239
240 fn compact_blas(&self, blas: &DispatchBlas) -> (Option<u64>, DispatchBlas);
241}
242
243pub trait ShaderModuleInterface: CommonTraits {
244 fn get_compilation_info(&self) -> Pin<Box<dyn ShaderCompilationInfoFuture>>;
245}
246pub trait BindGroupLayoutInterface: CommonTraits {}
247pub trait BindGroupInterface: CommonTraits {}
248pub trait TextureViewInterface: CommonTraits {}
249pub trait SamplerInterface: CommonTraits {}
250pub trait BufferInterface: CommonTraits {
251 fn map_async(
252 &self,
253 mode: crate::MapMode,
254 range: Range<crate::BufferAddress>,
255 callback: BufferMapCallback,
256 );
257 fn get_mapped_range(&self, sub_range: Range<crate::BufferAddress>)
258 -> DispatchBufferMappedRange;
259
260 fn unmap(&self);
261
262 fn destroy(&self);
263}
264pub trait TextureInterface: CommonTraits {
265 fn create_view(&self, desc: &crate::TextureViewDescriptor<'_>) -> DispatchTextureView;
266
267 fn destroy(&self);
268}
269pub trait ExternalTextureInterface: CommonTraits {
270 fn destroy(&self);
271}
272pub trait BlasInterface: CommonTraits {
273 fn prepare_compact_async(&self, callback: BlasCompactCallback);
274 fn ready_for_compaction(&self) -> bool;
275}
276pub trait TlasInterface: CommonTraits {}
277pub trait QuerySetInterface: CommonTraits {}
278pub trait PipelineLayoutInterface: CommonTraits {}
279pub trait RenderPipelineInterface: CommonTraits {
280 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
281}
282pub trait ComputePipelineInterface: CommonTraits {
283 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
284}
285pub trait PipelineCacheInterface: CommonTraits {
286 fn get_data(&self) -> Option<Vec<u8>>;
287}
288pub trait CommandEncoderInterface: CommonTraits {
289 fn copy_buffer_to_buffer(
290 &self,
291 source: &DispatchBuffer,
292 source_offset: crate::BufferAddress,
293 destination: &DispatchBuffer,
294 destination_offset: crate::BufferAddress,
295 copy_size: Option<crate::BufferAddress>,
296 );
297 fn copy_buffer_to_texture(
298 &self,
299 source: crate::TexelCopyBufferInfo<'_>,
300 destination: crate::TexelCopyTextureInfo<'_>,
301 copy_size: crate::Extent3d,
302 );
303 fn copy_texture_to_buffer(
304 &self,
305 source: crate::TexelCopyTextureInfo<'_>,
306 destination: crate::TexelCopyBufferInfo<'_>,
307 copy_size: crate::Extent3d,
308 );
309 fn copy_texture_to_texture(
310 &self,
311 source: crate::TexelCopyTextureInfo<'_>,
312 destination: crate::TexelCopyTextureInfo<'_>,
313 copy_size: crate::Extent3d,
314 );
315
316 fn begin_compute_pass(&self, desc: &crate::ComputePassDescriptor<'_>) -> DispatchComputePass;
317 fn begin_render_pass(&self, desc: &crate::RenderPassDescriptor<'_>) -> DispatchRenderPass;
318 fn finish(&mut self) -> DispatchCommandBuffer;
319
320 fn clear_texture(
321 &self,
322 texture: &DispatchTexture,
323 subresource_range: &crate::ImageSubresourceRange,
324 );
325 fn clear_buffer(
326 &self,
327 buffer: &DispatchBuffer,
328 offset: crate::BufferAddress,
329 size: Option<crate::BufferAddress>,
330 );
331
332 fn insert_debug_marker(&self, label: &str);
333 fn push_debug_group(&self, label: &str);
334 fn pop_debug_group(&self);
335
336 fn write_timestamp(&self, query_set: &DispatchQuerySet, query_index: u32);
337 fn resolve_query_set(
338 &self,
339 query_set: &DispatchQuerySet,
340 first_query: u32,
341 query_count: u32,
342 destination: &DispatchBuffer,
343 destination_offset: crate::BufferAddress,
344 );
345 fn mark_acceleration_structures_built<'a>(
346 &self,
347 blas: &mut dyn Iterator<Item = &'a Blas>,
348 tlas: &mut dyn Iterator<Item = &'a Tlas>,
349 );
350
351 fn build_acceleration_structures<'a>(
352 &self,
353 blas: &mut dyn Iterator<Item = &'a crate::BlasBuildEntry<'a>>,
354 tlas: &mut dyn Iterator<Item = &'a crate::Tlas>,
355 );
356
357 fn transition_resources<'a>(
358 &mut self,
359 buffer_transitions: &mut dyn Iterator<Item = wgt::BufferTransition<&'a DispatchBuffer>>,
360 texture_transitions: &mut dyn Iterator<Item = wgt::TextureTransition<&'a DispatchTexture>>,
361 );
362}
363pub trait ComputePassInterface: CommonTraits {
364 fn set_pipeline(&mut self, pipeline: &DispatchComputePipeline);
365 fn set_bind_group(
366 &mut self,
367 index: u32,
368 bind_group: Option<&DispatchBindGroup>,
369 offsets: &[crate::DynamicOffset],
370 );
371 fn set_push_constants(&mut self, offset: u32, data: &[u8]);
372
373 fn insert_debug_marker(&mut self, label: &str);
374 fn push_debug_group(&mut self, group_label: &str);
375 fn pop_debug_group(&mut self);
376
377 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
378 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
379 fn end_pipeline_statistics_query(&mut self);
380
381 fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32);
382 fn dispatch_workgroups_indirect(
383 &mut self,
384 indirect_buffer: &DispatchBuffer,
385 indirect_offset: crate::BufferAddress,
386 );
387 fn end(&mut self);
388}
389pub trait RenderPassInterface: CommonTraits {
390 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
391 fn set_bind_group(
392 &mut self,
393 index: u32,
394 bind_group: Option<&DispatchBindGroup>,
395 offsets: &[crate::DynamicOffset],
396 );
397 fn set_index_buffer(
398 &mut self,
399 buffer: &DispatchBuffer,
400 index_format: crate::IndexFormat,
401 offset: crate::BufferAddress,
402 size: Option<crate::BufferSize>,
403 );
404 fn set_vertex_buffer(
405 &mut self,
406 slot: u32,
407 buffer: &DispatchBuffer,
408 offset: crate::BufferAddress,
409 size: Option<crate::BufferSize>,
410 );
411 fn set_push_constants(&mut self, stages: crate::ShaderStages, offset: u32, data: &[u8]);
412 fn set_blend_constant(&mut self, color: crate::Color);
413 fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
414 fn set_viewport(
415 &mut self,
416 x: f32,
417 y: f32,
418 width: f32,
419 height: f32,
420 min_depth: f32,
421 max_depth: f32,
422 );
423 fn set_stencil_reference(&mut self, reference: u32);
424
425 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
426 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
427 fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32);
428 fn draw_indirect(
429 &mut self,
430 indirect_buffer: &DispatchBuffer,
431 indirect_offset: crate::BufferAddress,
432 );
433 fn draw_indexed_indirect(
434 &mut self,
435 indirect_buffer: &DispatchBuffer,
436 indirect_offset: crate::BufferAddress,
437 );
438 fn draw_mesh_tasks_indirect(
439 &mut self,
440 indirect_buffer: &DispatchBuffer,
441 indirect_offset: crate::BufferAddress,
442 );
443
444 fn multi_draw_indirect(
445 &mut self,
446 indirect_buffer: &DispatchBuffer,
447 indirect_offset: crate::BufferAddress,
448 count: u32,
449 );
450 fn multi_draw_indexed_indirect(
451 &mut self,
452 indirect_buffer: &DispatchBuffer,
453 indirect_offset: crate::BufferAddress,
454 count: u32,
455 );
456 fn multi_draw_indirect_count(
457 &mut self,
458 indirect_buffer: &DispatchBuffer,
459 indirect_offset: crate::BufferAddress,
460 count_buffer: &DispatchBuffer,
461 count_buffer_offset: crate::BufferAddress,
462 max_count: u32,
463 );
464 fn multi_draw_mesh_tasks_indirect(
465 &mut self,
466 indirect_buffer: &DispatchBuffer,
467 indirect_offset: crate::BufferAddress,
468 count: u32,
469 );
470 fn multi_draw_indexed_indirect_count(
471 &mut self,
472 indirect_buffer: &DispatchBuffer,
473 indirect_offset: crate::BufferAddress,
474 count_buffer: &DispatchBuffer,
475 count_buffer_offset: crate::BufferAddress,
476 max_count: u32,
477 );
478 fn multi_draw_mesh_tasks_indirect_count(
479 &mut self,
480 indirect_buffer: &DispatchBuffer,
481 indirect_offset: crate::BufferAddress,
482 count_buffer: &DispatchBuffer,
483 count_buffer_offset: crate::BufferAddress,
484 max_count: u32,
485 );
486
487 fn insert_debug_marker(&mut self, label: &str);
488 fn push_debug_group(&mut self, group_label: &str);
489 fn pop_debug_group(&mut self);
490
491 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
492 fn begin_occlusion_query(&mut self, query_index: u32);
493 fn end_occlusion_query(&mut self);
494 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
495 fn end_pipeline_statistics_query(&mut self);
496
497 fn execute_bundles(&mut self, render_bundles: &mut dyn Iterator<Item = &DispatchRenderBundle>);
498
499 fn end(&mut self);
500}
501
502pub trait RenderBundleEncoderInterface: CommonTraits {
503 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
504 fn set_bind_group(
505 &mut self,
506 index: u32,
507 bind_group: Option<&DispatchBindGroup>,
508 offsets: &[crate::DynamicOffset],
509 );
510 fn set_index_buffer(
511 &mut self,
512 buffer: &DispatchBuffer,
513 index_format: crate::IndexFormat,
514 offset: crate::BufferAddress,
515 size: Option<crate::BufferSize>,
516 );
517 fn set_vertex_buffer(
518 &mut self,
519 slot: u32,
520 buffer: &DispatchBuffer,
521 offset: crate::BufferAddress,
522 size: Option<crate::BufferSize>,
523 );
524 fn set_push_constants(&mut self, stages: crate::ShaderStages, offset: u32, data: &[u8]);
525
526 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
527 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
528 fn draw_indirect(
529 &mut self,
530 indirect_buffer: &DispatchBuffer,
531 indirect_offset: crate::BufferAddress,
532 );
533 fn draw_indexed_indirect(
534 &mut self,
535 indirect_buffer: &DispatchBuffer,
536 indirect_offset: crate::BufferAddress,
537 );
538
539 fn finish(self, desc: &crate::RenderBundleDescriptor<'_>) -> DispatchRenderBundle
540 where
541 Self: Sized;
542}
543
544pub trait CommandBufferInterface: CommonTraits {}
545pub trait RenderBundleInterface: CommonTraits {}
546
547pub trait SurfaceInterface: CommonTraits {
548 fn get_capabilities(&self, adapter: &DispatchAdapter) -> crate::SurfaceCapabilities;
549
550 fn configure(&self, device: &DispatchDevice, config: &crate::SurfaceConfiguration);
551 fn get_current_texture(
552 &self,
553 ) -> (
554 Option<DispatchTexture>,
555 crate::SurfaceStatus,
556 DispatchSurfaceOutputDetail,
557 );
558}
559
560pub trait SurfaceOutputDetailInterface: CommonTraits {
561 fn present(&self);
562 fn texture_discard(&self);
563}
564
565pub trait QueueWriteBufferInterface: CommonTraits {
566 fn slice(&self) -> &[u8];
567
568 fn slice_mut(&mut self) -> &mut [u8];
569}
570
571pub trait BufferMappedRangeInterface: CommonTraits {
572 fn slice(&self) -> &[u8];
573 fn slice_mut(&mut self) -> &mut [u8];
574
575 #[cfg(webgpu)]
576 fn as_uint8array(&self) -> &js_sys::Uint8Array;
577}
578
579macro_rules! dispatch_types {
590 (
591 ref type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
592 ) => {
593 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
594 pub enum $name {
595 #[cfg(wgpu_core)]
596 Core(Arc<$core_type>),
597 #[cfg(webgpu)]
598 WebGPU(Arc<$webgpu_type>),
599 #[allow(clippy::allow_attributes, private_interfaces)]
600 #[cfg(custom)]
601 Custom($custom_type),
602 }
603
604 impl $name {
605 #[cfg(wgpu_core)]
606 #[inline]
607 #[allow(clippy::allow_attributes, unused)]
608 pub fn as_core(&self) -> &$core_type {
609 match self {
610 Self::Core(value) => value,
611 _ => panic!(concat!(stringify!($name), " is not core")),
612 }
613 }
614
615 #[cfg(wgpu_core)]
616 #[inline]
617 #[allow(clippy::allow_attributes, unused)]
618 pub fn as_core_opt(&self) -> Option<&$core_type> {
619 match self {
620 Self::Core(value) => Some(value),
621 _ => None,
622 }
623 }
624
625 #[cfg(custom)]
626 #[inline]
627 #[allow(clippy::allow_attributes, unused)]
628 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
629 match self {
630 Self::Custom(value) => value.downcast(),
631 _ => None,
632 }
633 }
634
635 #[cfg(webgpu)]
636 #[inline]
637 #[allow(clippy::allow_attributes, unused)]
638 pub fn as_webgpu(&self) -> &$webgpu_type {
639 match self {
640 Self::WebGPU(value) => value,
641 _ => panic!(concat!(stringify!($name), " is not webgpu")),
642 }
643 }
644
645 #[cfg(webgpu)]
646 #[inline]
647 #[allow(clippy::allow_attributes, unused)]
648 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
649 match self {
650 Self::WebGPU(value) => Some(value),
651 _ => None,
652 }
653 }
654
655 #[cfg(custom)]
656 #[inline]
657 pub fn custom<T: $interface>(t: T) -> Self {
658 Self::Custom($custom_type::new(t))
659 }
660 }
661
662 #[cfg(wgpu_core)]
663 impl From<$core_type> for $name {
664 #[inline]
665 fn from(value: $core_type) -> Self {
666 Self::Core(Arc::new(value))
667 }
668 }
669
670 #[cfg(webgpu)]
671 impl From<$webgpu_type> for $name {
672 #[inline]
673 fn from(value: $webgpu_type) -> Self {
674 Self::WebGPU(Arc::new(value))
675 }
676 }
677
678 impl core::ops::Deref for $name {
679 type Target = dyn $interface;
680
681 #[inline]
682 fn deref(&self) -> &Self::Target {
683 match self {
684 #[cfg(wgpu_core)]
685 Self::Core(value) => value.as_ref(),
686 #[cfg(webgpu)]
687 Self::WebGPU(value) => value.as_ref(),
688 #[cfg(custom)]
689 Self::Custom(value) => value.deref(),
690 #[cfg(not(any(wgpu_core, webgpu)))]
691 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
692 }
693 }
694 }
695 };
696 (
697 mut type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
698 ) => {
699 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
700 pub enum $name {
701 #[cfg(wgpu_core)]
702 Core($core_type),
703 #[cfg(webgpu)]
704 WebGPU($webgpu_type),
705 #[allow(clippy::allow_attributes, private_interfaces)]
706 #[cfg(custom)]
707 Custom($custom_type),
708 }
709
710 impl $name {
711 #[cfg(wgpu_core)]
712 #[inline]
713 #[allow(clippy::allow_attributes, unused)]
714 pub fn as_core(&self) -> &$core_type {
715 match self {
716 Self::Core(value) => value,
717 _ => panic!(concat!(stringify!($name), " is not core")),
718 }
719 }
720
721 #[cfg(wgpu_core)]
722 #[inline]
723 #[allow(clippy::allow_attributes, unused)]
724 pub fn as_core_mut(&mut self) -> &mut $core_type {
725 match self {
726 Self::Core(value) => value,
727 _ => panic!(concat!(stringify!($name), " is not core")),
728 }
729 }
730
731 #[cfg(wgpu_core)]
732 #[inline]
733 #[allow(clippy::allow_attributes, unused)]
734 pub fn as_core_opt(&self) -> Option<&$core_type> {
735 match self {
736 Self::Core(value) => Some(value),
737 _ => None,
738 }
739 }
740
741 #[cfg(wgpu_core)]
742 #[inline]
743 #[allow(clippy::allow_attributes, unused)]
744 pub fn as_core_mut_opt(
745 &mut self,
746 ) -> Option<&mut $core_type> {
747 match self {
748 Self::Core(value) => Some(value),
749 _ => None,
750 }
751 }
752
753 #[cfg(custom)]
754 #[inline]
755 #[allow(clippy::allow_attributes, unused)]
756 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
757 match self {
758 Self::Custom(value) => value.downcast(),
759 _ => None,
760 }
761 }
762
763 #[cfg(webgpu)]
764 #[inline]
765 #[allow(clippy::allow_attributes, unused)]
766 pub fn as_webgpu(&self) -> &$webgpu_type {
767 match self {
768 Self::WebGPU(value) => value,
769 _ => panic!(concat!(stringify!($name), " is not webgpu")),
770 }
771 }
772
773 #[cfg(webgpu)]
774 #[inline]
775 #[allow(clippy::allow_attributes, unused)]
776 pub fn as_webgpu_mut(&mut self) -> &mut $webgpu_type {
777 match self {
778 Self::WebGPU(value) => value,
779 _ => panic!(concat!(stringify!($name), " is not webgpu")),
780 }
781 }
782
783 #[cfg(webgpu)]
784 #[inline]
785 #[allow(clippy::allow_attributes, unused)]
786 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
787 match self {
788 Self::WebGPU(value) => Some(value),
789 _ => None,
790 }
791 }
792
793 #[cfg(webgpu)]
794 #[inline]
795 #[allow(clippy::allow_attributes, unused)]
796 pub fn as_webgpu_mut_opt(
797 &mut self,
798 ) -> Option<&mut $webgpu_type> {
799 match self {
800 Self::WebGPU(value) => Some(value),
801 _ => None,
802 }
803 }
804
805 #[cfg(custom)]
806 #[inline]
807 pub fn custom<T: $interface>(t: T) -> Self {
808 Self::Custom($custom_type::new(t))
809 }
810 }
811
812 #[cfg(wgpu_core)]
813 impl From<$core_type> for $name {
814 #[inline]
815 fn from(value: $core_type) -> Self {
816 Self::Core(value)
817 }
818 }
819
820 #[cfg(webgpu)]
821 impl From<$webgpu_type> for $name {
822 #[inline]
823 fn from(value: $webgpu_type) -> Self {
824 Self::WebGPU(value)
825 }
826 }
827
828 impl core::ops::Deref for $name {
829 type Target = dyn $interface;
830
831 #[inline]
832 fn deref(&self) -> &Self::Target {
833 match self {
834 #[cfg(wgpu_core)]
835 Self::Core(value) => value,
836 #[cfg(webgpu)]
837 Self::WebGPU(value) => value,
838 #[cfg(custom)]
839 Self::Custom(value) => value.deref(),
840 #[cfg(not(any(wgpu_core, webgpu)))]
841 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
842 }
843 }
844 }
845
846 impl core::ops::DerefMut for $name {
847 #[inline]
848 fn deref_mut(&mut self) -> &mut Self::Target {
849 match self {
850 #[cfg(wgpu_core)]
851 Self::Core(value) => value,
852 #[cfg(webgpu)]
853 Self::WebGPU(value) => value,
854 #[cfg(custom)]
855 Self::Custom(value) => value.deref_mut(),
856 #[cfg(not(any(wgpu_core, webgpu)))]
857 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
858 }
859 }
860 }
861 };
862}
863
864dispatch_types! {ref type DispatchInstance: InstanceInterface = ContextWgpuCore, ContextWebGpu, DynContext}
865dispatch_types! {ref type DispatchAdapter: AdapterInterface = CoreAdapter, WebAdapter, DynAdapter}
866dispatch_types! {ref type DispatchDevice: DeviceInterface = CoreDevice, WebDevice, DynDevice}
867dispatch_types! {ref type DispatchQueue: QueueInterface = CoreQueue, WebQueue, DynQueue}
868dispatch_types! {ref type DispatchShaderModule: ShaderModuleInterface = CoreShaderModule, WebShaderModule, DynShaderModule}
869dispatch_types! {ref type DispatchBindGroupLayout: BindGroupLayoutInterface = CoreBindGroupLayout, WebBindGroupLayout, DynBindGroupLayout}
870dispatch_types! {ref type DispatchBindGroup: BindGroupInterface = CoreBindGroup, WebBindGroup, DynBindGroup}
871dispatch_types! {ref type DispatchTextureView: TextureViewInterface = CoreTextureView, WebTextureView, DynTextureView}
872dispatch_types! {ref type DispatchSampler: SamplerInterface = CoreSampler, WebSampler, DynSampler}
873dispatch_types! {ref type DispatchBuffer: BufferInterface = CoreBuffer, WebBuffer, DynBuffer}
874dispatch_types! {ref type DispatchTexture: TextureInterface = CoreTexture, WebTexture, DynTexture}
875dispatch_types! {ref type DispatchExternalTexture: ExternalTextureInterface = CoreExternalTexture, WebExternalTexture, DynExternalTexture}
876dispatch_types! {ref type DispatchBlas: BlasInterface = CoreBlas, WebBlas, DynBlas}
877dispatch_types! {ref type DispatchTlas: TlasInterface = CoreTlas, WebTlas, DynTlas}
878dispatch_types! {ref type DispatchQuerySet: QuerySetInterface = CoreQuerySet, WebQuerySet, DynQuerySet}
879dispatch_types! {ref type DispatchPipelineLayout: PipelineLayoutInterface = CorePipelineLayout, WebPipelineLayout, DynPipelineLayout}
880dispatch_types! {ref type DispatchRenderPipeline: RenderPipelineInterface = CoreRenderPipeline, WebRenderPipeline, DynRenderPipeline}
881dispatch_types! {ref type DispatchComputePipeline: ComputePipelineInterface = CoreComputePipeline, WebComputePipeline, DynComputePipeline}
882dispatch_types! {ref type DispatchPipelineCache: PipelineCacheInterface = CorePipelineCache, WebPipelineCache, DynPipelineCache}
883dispatch_types! {mut type DispatchCommandEncoder: CommandEncoderInterface = CoreCommandEncoder, WebCommandEncoder, DynCommandEncoder}
884dispatch_types! {mut type DispatchComputePass: ComputePassInterface = CoreComputePass, WebComputePassEncoder, DynComputePass}
885dispatch_types! {mut type DispatchRenderPass: RenderPassInterface = CoreRenderPass, WebRenderPassEncoder, DynRenderPass}
886dispatch_types! {ref type DispatchCommandBuffer: CommandBufferInterface = CoreCommandBuffer, WebCommandBuffer, DynCommandBuffer}
887dispatch_types! {mut type DispatchRenderBundleEncoder: RenderBundleEncoderInterface = CoreRenderBundleEncoder, WebRenderBundleEncoder, DynRenderBundleEncoder}
888dispatch_types! {ref type DispatchRenderBundle: RenderBundleInterface = CoreRenderBundle, WebRenderBundle, DynRenderBundle}
889dispatch_types! {ref type DispatchSurface: SurfaceInterface = CoreSurface, WebSurface, DynSurface}
890dispatch_types! {ref type DispatchSurfaceOutputDetail: SurfaceOutputDetailInterface = CoreSurfaceOutputDetail, WebSurfaceOutputDetail, DynSurfaceOutputDetail}
891dispatch_types! {mut type DispatchQueueWriteBuffer: QueueWriteBufferInterface = CoreQueueWriteBuffer, WebQueueWriteBuffer, DynQueueWriteBuffer}
892dispatch_types! {mut type DispatchBufferMappedRange: BufferMappedRangeInterface = CoreBufferMappedRange, WebBufferMappedRange, DynBufferMappedRange}