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