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 {
305 fn destroy(&self);
306}
307pub trait PipelineLayoutInterface: CommonTraits {}
308pub trait RenderPipelineInterface: CommonTraits {
309 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
310}
311pub trait ComputePipelineInterface: CommonTraits {
312 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
313}
314pub trait PipelineCacheInterface: CommonTraits {
315 fn get_data(&self) -> Option<Vec<u8>>;
316}
317pub trait CommandEncoderInterface: CommonTraits {
318 fn copy_buffer_to_buffer(
319 &self,
320 source: &DispatchBuffer,
321 source_offset: crate::BufferAddress,
322 destination: &DispatchBuffer,
323 destination_offset: crate::BufferAddress,
324 copy_size: Option<crate::BufferAddress>,
325 );
326 fn copy_buffer_to_texture(
327 &self,
328 source: crate::TexelCopyBufferInfo<'_>,
329 destination: crate::TexelCopyTextureInfo<'_>,
330 copy_size: crate::Extent3d,
331 );
332 fn copy_texture_to_buffer(
333 &self,
334 source: crate::TexelCopyTextureInfo<'_>,
335 destination: crate::TexelCopyBufferInfo<'_>,
336 copy_size: crate::Extent3d,
337 );
338 fn copy_texture_to_texture(
339 &self,
340 source: crate::TexelCopyTextureInfo<'_>,
341 destination: crate::TexelCopyTextureInfo<'_>,
342 copy_size: crate::Extent3d,
343 );
344
345 fn begin_compute_pass(&self, desc: &crate::ComputePassDescriptor<'_>) -> DispatchComputePass;
346 fn begin_render_pass(&self, desc: &crate::RenderPassDescriptor<'_>) -> DispatchRenderPass;
347 fn finish(&mut self) -> DispatchCommandBuffer;
348
349 fn clear_texture(
350 &self,
351 texture: &DispatchTexture,
352 subresource_range: &crate::ImageSubresourceRange,
353 );
354 fn clear_buffer(
355 &self,
356 buffer: &DispatchBuffer,
357 offset: crate::BufferAddress,
358 size: Option<crate::BufferAddress>,
359 );
360
361 fn insert_debug_marker(&self, label: &str);
362 fn push_debug_group(&self, label: &str);
363 fn pop_debug_group(&self);
364
365 fn write_timestamp(&self, query_set: &DispatchQuerySet, query_index: u32);
366 fn resolve_query_set(
367 &self,
368 query_set: &DispatchQuerySet,
369 first_query: u32,
370 query_count: u32,
371 destination: &DispatchBuffer,
372 destination_offset: crate::BufferAddress,
373 );
374 fn mark_acceleration_structures_built<'a>(
375 &self,
376 blas: &mut dyn Iterator<Item = &'a Blas>,
377 tlas: &mut dyn Iterator<Item = &'a Tlas>,
378 );
379
380 fn build_acceleration_structures<'a>(
381 &self,
382 blas: &mut dyn Iterator<Item = &'a crate::BlasBuildEntry<'a>>,
383 tlas: &mut dyn Iterator<Item = &'a crate::Tlas>,
384 );
385
386 fn transition_resources<'a>(
387 &mut self,
388 buffer_transitions: &mut dyn Iterator<Item = wgt::BufferTransition<&'a DispatchBuffer>>,
389 texture_transitions: &mut dyn Iterator<Item = wgt::TextureTransition<&'a DispatchTexture>>,
390 );
391}
392pub trait ComputePassInterface: CommonTraits + Drop {
393 fn set_pipeline(&mut self, pipeline: &DispatchComputePipeline);
394 fn set_bind_group(
395 &mut self,
396 index: u32,
397 bind_group: Option<&DispatchBindGroup>,
398 offsets: &[crate::DynamicOffset],
399 );
400 fn set_immediates(&mut self, offset: u32, data: &[u8]);
401
402 fn insert_debug_marker(&mut self, label: &str);
403 fn push_debug_group(&mut self, group_label: &str);
404 fn pop_debug_group(&mut self);
405
406 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
407 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
408 fn end_pipeline_statistics_query(&mut self);
409
410 fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32);
411 fn dispatch_workgroups_indirect(
412 &mut self,
413 indirect_buffer: &DispatchBuffer,
414 indirect_offset: crate::BufferAddress,
415 );
416
417 fn transition_resources<'a>(
418 &mut self,
419 buffer_transitions: &mut dyn Iterator<Item = wgt::BufferTransition<&'a DispatchBuffer>>,
420 texture_transitions: &mut dyn Iterator<
421 Item = wgt::TextureTransition<&'a DispatchTextureView>,
422 >,
423 );
424}
425pub trait RenderPassInterface: CommonTraits + Drop {
426 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
427 fn set_bind_group(
428 &mut self,
429 index: u32,
430 bind_group: Option<&DispatchBindGroup>,
431 offsets: &[crate::DynamicOffset],
432 );
433 fn set_index_buffer(
434 &mut self,
435 buffer: &DispatchBuffer,
436 index_format: crate::IndexFormat,
437 offset: crate::BufferAddress,
438 size: Option<crate::BufferSize>,
439 );
440 fn set_vertex_buffer(
441 &mut self,
442 slot: u32,
443 buffer: Option<&DispatchBuffer>,
444 offset: crate::BufferAddress,
445 size: Option<crate::BufferSize>,
446 );
447 fn set_immediates(&mut self, offset: u32, data: &[u8]);
448 fn set_blend_constant(&mut self, color: crate::Color);
449 fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
450 fn set_viewport(
451 &mut self,
452 x: f32,
453 y: f32,
454 width: f32,
455 height: f32,
456 min_depth: f32,
457 max_depth: f32,
458 );
459 fn set_stencil_reference(&mut self, reference: u32);
460
461 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
462 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
463 fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32);
464 fn draw_indirect(
465 &mut self,
466 indirect_buffer: &DispatchBuffer,
467 indirect_offset: crate::BufferAddress,
468 );
469 fn draw_indexed_indirect(
470 &mut self,
471 indirect_buffer: &DispatchBuffer,
472 indirect_offset: crate::BufferAddress,
473 );
474 fn draw_mesh_tasks_indirect(
475 &mut self,
476 indirect_buffer: &DispatchBuffer,
477 indirect_offset: crate::BufferAddress,
478 );
479
480 fn multi_draw_indirect(
481 &mut self,
482 indirect_buffer: &DispatchBuffer,
483 indirect_offset: crate::BufferAddress,
484 count: u32,
485 );
486 fn multi_draw_indexed_indirect(
487 &mut self,
488 indirect_buffer: &DispatchBuffer,
489 indirect_offset: crate::BufferAddress,
490 count: u32,
491 );
492 fn multi_draw_indirect_count(
493 &mut self,
494 indirect_buffer: &DispatchBuffer,
495 indirect_offset: crate::BufferAddress,
496 count_buffer: &DispatchBuffer,
497 count_buffer_offset: crate::BufferAddress,
498 max_count: u32,
499 );
500 fn multi_draw_mesh_tasks_indirect(
501 &mut self,
502 indirect_buffer: &DispatchBuffer,
503 indirect_offset: crate::BufferAddress,
504 count: u32,
505 );
506 fn multi_draw_indexed_indirect_count(
507 &mut self,
508 indirect_buffer: &DispatchBuffer,
509 indirect_offset: crate::BufferAddress,
510 count_buffer: &DispatchBuffer,
511 count_buffer_offset: crate::BufferAddress,
512 max_count: u32,
513 );
514 fn multi_draw_mesh_tasks_indirect_count(
515 &mut self,
516 indirect_buffer: &DispatchBuffer,
517 indirect_offset: crate::BufferAddress,
518 count_buffer: &DispatchBuffer,
519 count_buffer_offset: crate::BufferAddress,
520 max_count: u32,
521 );
522
523 fn insert_debug_marker(&mut self, label: &str);
524 fn push_debug_group(&mut self, group_label: &str);
525 fn pop_debug_group(&mut self);
526
527 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
528 fn begin_occlusion_query(&mut self, query_index: u32);
529 fn end_occlusion_query(&mut self);
530 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
531 fn end_pipeline_statistics_query(&mut self);
532
533 fn execute_bundles(&mut self, render_bundles: &mut dyn Iterator<Item = &DispatchRenderBundle>);
534}
535
536pub trait RenderBundleEncoderInterface: CommonTraits {
537 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
538 fn set_bind_group(
539 &mut self,
540 index: u32,
541 bind_group: Option<&DispatchBindGroup>,
542 offsets: &[crate::DynamicOffset],
543 );
544 fn set_index_buffer(
545 &mut self,
546 buffer: &DispatchBuffer,
547 index_format: crate::IndexFormat,
548 offset: crate::BufferAddress,
549 size: Option<crate::BufferSize>,
550 );
551 fn set_vertex_buffer(
552 &mut self,
553 slot: u32,
554 buffer: Option<&DispatchBuffer>,
555 offset: crate::BufferAddress,
556 size: Option<crate::BufferSize>,
557 );
558 fn set_immediates(&mut self, offset: u32, data: &[u8]);
559
560 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
561 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
562 fn draw_indirect(
563 &mut self,
564 indirect_buffer: &DispatchBuffer,
565 indirect_offset: crate::BufferAddress,
566 );
567 fn draw_indexed_indirect(
568 &mut self,
569 indirect_buffer: &DispatchBuffer,
570 indirect_offset: crate::BufferAddress,
571 );
572
573 fn finish(self, desc: &crate::RenderBundleDescriptor<'_>) -> DispatchRenderBundle
574 where
575 Self: Sized;
576
577 #[cfg(custom)]
588 fn finish_boxed(
589 self: Box<Self>,
590 desc: &crate::RenderBundleDescriptor<'_>,
591 ) -> DispatchRenderBundle;
592}
593
594pub trait CommandBufferInterface: CommonTraits {}
595pub trait RenderBundleInterface: CommonTraits {}
596
597pub trait SurfaceInterface: CommonTraits {
598 fn get_capabilities(&self, adapter: &DispatchAdapter) -> crate::SurfaceCapabilities;
599
600 fn configure(&self, device: &DispatchDevice, config: &crate::SurfaceConfiguration);
601 fn get_current_texture(
602 &self,
603 ) -> (
604 Option<DispatchTexture>,
605 crate::SurfaceStatus,
606 DispatchSurfaceOutputDetail,
607 );
608}
609
610pub trait SurfaceOutputDetailInterface: CommonTraits {
611 fn texture_discard(&self);
612}
613
614pub trait QueueWriteBufferInterface: CommonTraits {
615 fn len(&self) -> usize;
616
617 unsafe fn write_slice(&mut self) -> WriteOnly<'_, [u8]>;
621}
622
623pub trait BufferMappedRangeInterface: CommonTraits {
624 #[cfg_attr(not(wgpu_core), expect(unused))]
626 fn len(&self) -> usize;
627
628 unsafe fn read_slice(&self) -> &[u8];
632
633 unsafe fn write_slice(&mut self) -> WriteOnly<'_, [u8]>;
637
638 #[cfg(webgpu)]
639 fn as_uint8array(&self) -> &js_sys::Uint8Array;
640}
641
642macro_rules! dispatch_types {
714 (
715 ref type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
716 ) => {
717 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
718 pub enum $name {
719 #[cfg(wgpu_core)]
720 Core(Arc<$core_type>),
721 #[cfg(webgpu)]
722 WebGPU($webgpu_type),
723 #[allow(clippy::allow_attributes, private_interfaces)]
724 #[cfg(custom)]
725 Custom($custom_type),
726 }
727
728 impl $name {
729 #[cfg(wgpu_core)]
730 #[inline]
731 #[allow(clippy::allow_attributes, unused)]
732 pub fn as_core(&self) -> &$core_type {
733 match self {
734 Self::Core(value) => value,
735 _ => panic!(concat!(stringify!($name), " is not core")),
736 }
737 }
738
739 #[cfg(wgpu_core)]
740 #[inline]
741 #[allow(clippy::allow_attributes, unused)]
742 pub fn as_core_opt(&self) -> Option<&$core_type> {
743 match self {
744 Self::Core(value) => Some(value),
745 _ => None,
746 }
747 }
748
749 #[cfg(custom)]
750 #[inline]
751 #[allow(clippy::allow_attributes, unused)]
752 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
753 match self {
754 Self::Custom(value) => value.downcast(),
755 _ => None,
756 }
757 }
758
759 #[cfg(webgpu)]
760 #[inline]
761 #[allow(clippy::allow_attributes, unused)]
762 pub fn as_webgpu(&self) -> &$webgpu_type {
763 match self {
764 Self::WebGPU(value) => value,
765 _ => panic!(concat!(stringify!($name), " is not webgpu")),
766 }
767 }
768
769 #[cfg(webgpu)]
770 #[inline]
771 #[allow(clippy::allow_attributes, unused)]
772 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
773 match self {
774 Self::WebGPU(value) => Some(value),
775 _ => None,
776 }
777 }
778
779 #[cfg(custom)]
780 #[inline]
781 pub fn custom<T: $interface>(t: T) -> Self {
782 Self::Custom($custom_type::new(t))
783 }
784 }
785
786 #[cfg(wgpu_core)]
787 impl From<$core_type> for $name {
788 #[inline]
789 fn from(value: $core_type) -> Self {
790 Self::Core(Arc::new(value))
791 }
792 }
793
794 #[cfg(webgpu)]
795 impl From<$webgpu_type> for $name {
796 #[inline]
797 fn from(value: $webgpu_type) -> Self {
798 Self::WebGPU(value)
799 }
800 }
801
802 impl core::ops::Deref for $name {
803 type Target = dyn $interface;
804
805 #[inline]
806 fn deref(&self) -> &Self::Target {
807 match self {
808 #[cfg(wgpu_core)]
809 Self::Core(value) => value.as_ref(),
810 #[cfg(webgpu)]
811 Self::WebGPU(value) => value,
812 #[cfg(custom)]
813 Self::Custom(value) => value.deref(),
814 #[cfg(not(any(wgpu_core, webgpu)))]
815 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
816 }
817 }
818 }
819 };
820 (
821 mut type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
822 ) => {
823 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
824 pub enum $name {
825 #[cfg(wgpu_core)]
826 Core($core_type),
827 #[cfg(webgpu)]
828 WebGPU($webgpu_type),
829 #[allow(clippy::allow_attributes, private_interfaces)]
830 #[cfg(custom)]
831 Custom($custom_type),
832 }
833
834 impl $name {
835 #[cfg(wgpu_core)]
836 #[inline]
837 #[allow(clippy::allow_attributes, unused)]
838 pub fn as_core(&self) -> &$core_type {
839 match self {
840 Self::Core(value) => value,
841 _ => panic!(concat!(stringify!($name), " is not core")),
842 }
843 }
844
845 #[cfg(wgpu_core)]
846 #[inline]
847 #[allow(clippy::allow_attributes, unused)]
848 pub fn as_core_mut(&mut self) -> &mut $core_type {
849 match self {
850 Self::Core(value) => value,
851 _ => panic!(concat!(stringify!($name), " is not core")),
852 }
853 }
854
855 #[cfg(wgpu_core)]
856 #[inline]
857 #[allow(clippy::allow_attributes, unused)]
858 pub fn as_core_opt(&self) -> Option<&$core_type> {
859 match self {
860 Self::Core(value) => Some(value),
861 _ => None,
862 }
863 }
864
865 #[cfg(wgpu_core)]
866 #[inline]
867 #[allow(clippy::allow_attributes, unused)]
868 pub fn as_core_mut_opt(
869 &mut self,
870 ) -> Option<&mut $core_type> {
871 match self {
872 Self::Core(value) => Some(value),
873 _ => None,
874 }
875 }
876
877 #[cfg(custom)]
878 #[inline]
879 #[allow(clippy::allow_attributes, unused)]
880 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
881 match self {
882 Self::Custom(value) => value.downcast(),
883 _ => None,
884 }
885 }
886
887 #[cfg(webgpu)]
888 #[inline]
889 #[allow(clippy::allow_attributes, unused)]
890 pub fn as_webgpu(&self) -> &$webgpu_type {
891 match self {
892 Self::WebGPU(value) => value,
893 _ => panic!(concat!(stringify!($name), " is not webgpu")),
894 }
895 }
896
897 #[cfg(webgpu)]
898 #[inline]
899 #[allow(clippy::allow_attributes, unused)]
900 pub fn as_webgpu_mut(&mut self) -> &mut $webgpu_type {
901 match self {
902 Self::WebGPU(value) => value,
903 _ => panic!(concat!(stringify!($name), " is not webgpu")),
904 }
905 }
906
907 #[cfg(webgpu)]
908 #[inline]
909 #[allow(clippy::allow_attributes, unused)]
910 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
911 match self {
912 Self::WebGPU(value) => Some(value),
913 _ => None,
914 }
915 }
916
917 #[cfg(webgpu)]
918 #[inline]
919 #[allow(clippy::allow_attributes, unused)]
920 pub fn as_webgpu_mut_opt(
921 &mut self,
922 ) -> Option<&mut $webgpu_type> {
923 match self {
924 Self::WebGPU(value) => Some(value),
925 _ => None,
926 }
927 }
928
929 #[cfg(custom)]
930 #[inline]
931 pub fn custom<T: $interface>(t: T) -> Self {
932 Self::Custom($custom_type::new(t))
933 }
934 }
935
936 #[cfg(wgpu_core)]
937 impl From<$core_type> for $name {
938 #[inline]
939 fn from(value: $core_type) -> Self {
940 Self::Core(value)
941 }
942 }
943
944 #[cfg(webgpu)]
945 impl From<$webgpu_type> for $name {
946 #[inline]
947 fn from(value: $webgpu_type) -> Self {
948 Self::WebGPU(value)
949 }
950 }
951
952 impl core::ops::Deref for $name {
953 type Target = dyn $interface;
954
955 #[inline]
956 fn deref(&self) -> &Self::Target {
957 match self {
958 #[cfg(wgpu_core)]
959 Self::Core(value) => value,
960 #[cfg(webgpu)]
961 Self::WebGPU(value) => value,
962 #[cfg(custom)]
963 Self::Custom(value) => value.deref(),
964 #[cfg(not(any(wgpu_core, webgpu)))]
965 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
966 }
967 }
968 }
969
970 impl core::ops::DerefMut for $name {
971 #[inline]
972 fn deref_mut(&mut self) -> &mut Self::Target {
973 match self {
974 #[cfg(wgpu_core)]
975 Self::Core(value) => value,
976 #[cfg(webgpu)]
977 Self::WebGPU(value) => value,
978 #[cfg(custom)]
979 Self::Custom(value) => value.deref_mut(),
980 #[cfg(not(any(wgpu_core, webgpu)))]
981 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
982 }
983 }
984 }
985 };
986}
987
988dispatch_types! {ref type DispatchInstance: InstanceInterface = ContextWgpuCore, ContextWebGpu, DynContext}
989dispatch_types! {ref type DispatchAdapter: AdapterInterface = CoreAdapter, WebAdapter, DynAdapter}
990dispatch_types! {ref type DispatchDevice: DeviceInterface = CoreDevice, WebDevice, DynDevice}
991dispatch_types! {ref type DispatchQueue: QueueInterface = CoreQueue, WebQueue, DynQueue}
992dispatch_types! {ref type DispatchShaderModule: ShaderModuleInterface = CoreShaderModule, WebShaderModule, DynShaderModule}
993dispatch_types! {ref type DispatchBindGroupLayout: BindGroupLayoutInterface = CoreBindGroupLayout, WebBindGroupLayout, DynBindGroupLayout}
994dispatch_types! {ref type DispatchBindGroup: BindGroupInterface = CoreBindGroup, WebBindGroup, DynBindGroup}
995dispatch_types! {ref type DispatchTextureView: TextureViewInterface = CoreTextureView, WebTextureView, DynTextureView}
996dispatch_types! {ref type DispatchSampler: SamplerInterface = CoreSampler, WebSampler, DynSampler}
997dispatch_types! {ref type DispatchBuffer: BufferInterface = CoreBuffer, WebBuffer, DynBuffer}
998dispatch_types! {ref type DispatchTexture: TextureInterface = CoreTexture, WebTexture, DynTexture}
999dispatch_types! {ref type DispatchExternalTexture: ExternalTextureInterface = CoreExternalTexture, WebExternalTexture, DynExternalTexture}
1000dispatch_types! {ref type DispatchBlas: BlasInterface = CoreBlas, WebBlas, DynBlas}
1001dispatch_types! {ref type DispatchTlas: TlasInterface = CoreTlas, WebTlas, DynTlas}
1002dispatch_types! {ref type DispatchQuerySet: QuerySetInterface = CoreQuerySet, WebQuerySet, DynQuerySet}
1003dispatch_types! {ref type DispatchPipelineLayout: PipelineLayoutInterface = CorePipelineLayout, WebPipelineLayout, DynPipelineLayout}
1004dispatch_types! {ref type DispatchRenderPipeline: RenderPipelineInterface = CoreRenderPipeline, WebRenderPipeline, DynRenderPipeline}
1005dispatch_types! {ref type DispatchComputePipeline: ComputePipelineInterface = CoreComputePipeline, WebComputePipeline, DynComputePipeline}
1006dispatch_types! {ref type DispatchPipelineCache: PipelineCacheInterface = CorePipelineCache, WebPipelineCache, DynPipelineCache}
1007dispatch_types! {mut type DispatchCommandEncoder: CommandEncoderInterface = CoreCommandEncoder, WebCommandEncoder, DynCommandEncoder}
1008dispatch_types! {mut type DispatchComputePass: ComputePassInterface = CoreComputePass, WebComputePassEncoder, DynComputePass}
1009dispatch_types! {mut type DispatchRenderPass: RenderPassInterface = CoreRenderPass, WebRenderPassEncoder, DynRenderPass}
1010dispatch_types! {mut type DispatchCommandBuffer: CommandBufferInterface = CoreCommandBuffer, WebCommandBuffer, DynCommandBuffer}
1011dispatch_types! {mut type DispatchRenderBundleEncoder: RenderBundleEncoderInterface = CoreRenderBundleEncoder, WebRenderBundleEncoder, DynRenderBundleEncoder}
1012dispatch_types! {ref type DispatchRenderBundle: RenderBundleInterface = CoreRenderBundle, WebRenderBundle, DynRenderBundle}
1013dispatch_types! {ref type DispatchSurface: SurfaceInterface = CoreSurface, WebSurface, DynSurface}
1014dispatch_types! {ref type DispatchSurfaceOutputDetail: SurfaceOutputDetailInterface = CoreSurfaceOutputDetail, WebSurfaceOutputDetail, DynSurfaceOutputDetail}
1015dispatch_types! {mut type DispatchQueueWriteBuffer: QueueWriteBufferInterface = CoreQueueWriteBuffer, WebQueueWriteBuffer, DynQueueWriteBuffer}
1016dispatch_types! {mut type DispatchBufferMappedRange: BufferMappedRangeInterface = CoreBufferMappedRange, WebBufferMappedRange, DynBufferMappedRange}