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