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