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