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