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