1#![allow(
15 drop_bounds,
16 reason = "This exists to remind implementors to impl drop."
17)]
18#![allow(clippy::too_many_arguments, reason = "It's fine.")]
19#![allow(
20 missing_docs,
21 clippy::missing_safety_doc,
22 reason = "Interfaces are not documented"
23)]
24#![allow(
25 clippy::len_without_is_empty,
26 reason = "trait is minimal, not ergonomic"
27)]
28
29use crate::{Blas, Tlas, WasmNotSend, WasmNotSendSync, WriteOnly};
30
31use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
32use core::{any::Any, fmt::Debug, future::Future, hash::Hash, ops::Range, pin::Pin};
33
34#[cfg(custom)]
35use crate::backend::custom::*;
36#[cfg(webgpu)]
37use crate::backend::webgpu::*;
38#[cfg(wgpu_core)]
39use crate::backend::wgpu_core::*;
40
41macro_rules! trait_alias {
45 ($name:ident: $($bound:tt)+) => {
46 pub trait $name: $($bound)+ {}
47 impl<T: $($bound)+> $name for T {}
48 };
49}
50
51trait_alias!(RequestAdapterFuture: Future<Output = Result<DispatchAdapter, wgt::RequestAdapterError>> + WasmNotSend + 'static);
53trait_alias!(RequestDeviceFuture: Future<Output = Result<(DispatchDevice, DispatchQueue), crate::RequestDeviceError>> + WasmNotSend + 'static);
54trait_alias!(PopErrorScopeFuture: Future<Output = Option<crate::Error>> + WasmNotSend + 'static);
55trait_alias!(ShaderCompilationInfoFuture: Future<Output = crate::CompilationInfo> + WasmNotSend + 'static);
56trait_alias!(EnumerateAdapterFuture: Future<Output = Vec<DispatchAdapter>> + WasmNotSend + 'static);
57
58#[cfg(send_sync)]
60pub type BoxDeviceLostCallback = Box<dyn FnOnce(crate::DeviceLostReason, String) + Send + 'static>;
61#[cfg(not(send_sync))]
62pub type BoxDeviceLostCallback = Box<dyn FnOnce(crate::DeviceLostReason, String) + 'static>;
63#[cfg(send_sync)]
64pub type BoxSubmittedWorkDoneCallback = Box<dyn FnOnce() + Send + 'static>;
65#[cfg(not(send_sync))]
66pub type BoxSubmittedWorkDoneCallback = Box<dyn FnOnce() + 'static>;
67#[cfg(send_sync)]
68pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + Send + 'static>;
69#[cfg(not(send_sync))]
70pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + 'static>;
71
72#[cfg(send_sync)]
73pub type BlasCompactCallback = Box<dyn FnOnce(Result<(), crate::BlasAsyncError>) + Send + 'static>;
74#[cfg(not(send_sync))]
75pub type BlasCompactCallback = Box<dyn FnOnce(Result<(), crate::BlasAsyncError>) + 'static>;
76
77#[cfg_attr(not(custom), expect(dead_code))]
79pub trait AsAny {
80 fn as_any(&self) -> &dyn Any;
81}
82
83impl<T: 'static> AsAny for T {
84 fn as_any(&self) -> &dyn Any {
85 self
86 }
87}
88
89trait_alias!(CommonTraits: AsAny + Any + Debug + WasmNotSendSync);
91
92pub trait InstanceInterface: CommonTraits {
93 fn new(desc: crate::InstanceDescriptor) -> Self
94 where
95 Self: Sized;
96
97 unsafe fn create_surface(
98 &self,
99 target: crate::SurfaceTargetUnsafe,
100 ) -> Result<DispatchSurface, crate::CreateSurfaceError>;
101
102 fn request_adapter(
103 &self,
104 options: &crate::RequestAdapterOptions<'_, '_>,
105 ) -> Pin<Box<dyn RequestAdapterFuture>>;
106
107 fn poll_all_devices(&self, force_wait: bool) -> bool;
108
109 #[cfg(feature = "wgsl")]
110 fn wgsl_language_features(&self) -> crate::WgslLanguageFeatures;
111
112 fn enumerate_adapters(&self, backends: crate::Backends)
113 -> Pin<Box<dyn EnumerateAdapterFuture>>;
114}
115
116pub trait AdapterInterface: CommonTraits {
117 fn request_device(
118 &self,
119 desc: &crate::DeviceDescriptor<'_>,
120 ) -> Pin<Box<dyn RequestDeviceFuture>>;
121
122 fn is_surface_supported(&self, surface: &DispatchSurface) -> bool;
123
124 fn features(&self) -> crate::Features;
125
126 fn limits(&self) -> crate::Limits;
127
128 fn downlevel_capabilities(&self) -> crate::DownlevelCapabilities;
129
130 fn get_info(&self) -> crate::AdapterInfo;
131
132 fn get_texture_format_features(
133 &self,
134 format: crate::TextureFormat,
135 ) -> crate::TextureFormatFeatures;
136
137 fn get_presentation_timestamp(&self) -> crate::PresentationTimestamp;
138
139 fn cooperative_matrix_properties(&self) -> Vec<crate::wgt::CooperativeMatrixProperties>;
140}
141
142pub trait DeviceInterface: CommonTraits {
143 fn features(&self) -> crate::Features;
144 fn limits(&self) -> crate::Limits;
145 fn adapter_info(&self) -> crate::AdapterInfo;
146
147 fn create_shader_module(
148 &self,
149 desc: crate::ShaderModuleDescriptor<'_>,
150 shader_bound_checks: crate::ShaderRuntimeChecks,
151 ) -> DispatchShaderModule;
152
153 unsafe fn create_shader_module_passthrough(
154 &self,
155 desc: &crate::ShaderModuleDescriptorPassthrough<'_>,
156 ) -> DispatchShaderModule;
157
158 fn create_bind_group_layout(
159 &self,
160 desc: &crate::BindGroupLayoutDescriptor<'_>,
161 ) -> DispatchBindGroupLayout;
162 fn create_bind_group(&self, desc: &crate::BindGroupDescriptor<'_>) -> DispatchBindGroup;
163 fn create_pipeline_layout(
164 &self,
165 desc: &crate::PipelineLayoutDescriptor<'_>,
166 ) -> DispatchPipelineLayout;
167 fn create_render_pipeline(
168 &self,
169 desc: &crate::RenderPipelineDescriptor<'_>,
170 ) -> DispatchRenderPipeline;
171 fn create_mesh_pipeline(
172 &self,
173 desc: &crate::MeshPipelineDescriptor<'_>,
174 ) -> DispatchRenderPipeline;
175 fn create_compute_pipeline(
176 &self,
177 desc: &crate::ComputePipelineDescriptor<'_>,
178 ) -> DispatchComputePipeline;
179 unsafe fn create_pipeline_cache(
180 &self,
181 desc: &crate::PipelineCacheDescriptor<'_>,
182 ) -> DispatchPipelineCache;
183 fn create_buffer(&self, desc: &crate::BufferDescriptor<'_>) -> DispatchBuffer;
184 fn create_texture(&self, desc: &crate::TextureDescriptor<'_>) -> DispatchTexture;
185 fn create_external_texture(
186 &self,
187 desc: &crate::ExternalTextureDescriptor<'_>,
188 planes: &[&crate::TextureView],
189 ) -> DispatchExternalTexture;
190 fn create_blas(
191 &self,
192 desc: &crate::CreateBlasDescriptor<'_>,
193 sizes: crate::BlasGeometrySizeDescriptors,
194 ) -> (Option<u64>, DispatchBlas);
195 fn create_tlas(&self, desc: &crate::CreateTlasDescriptor<'_>) -> DispatchTlas;
196 fn create_sampler(&self, desc: &crate::SamplerDescriptor<'_>) -> DispatchSampler;
197 fn create_query_set(&self, desc: &crate::QuerySetDescriptor<'_>) -> DispatchQuerySet;
198 fn create_command_encoder(
199 &self,
200 desc: &crate::CommandEncoderDescriptor<'_>,
201 ) -> DispatchCommandEncoder;
202 fn create_render_bundle_encoder(
203 &self,
204 desc: &crate::RenderBundleEncoderDescriptor<'_>,
205 ) -> DispatchRenderBundleEncoder;
206
207 fn set_device_lost_callback(&self, device_lost_callback: BoxDeviceLostCallback);
208
209 fn on_uncaptured_error(&self, handler: Arc<dyn crate::UncapturedErrorHandler>);
210 fn push_error_scope(&self, filter: crate::ErrorFilter) -> u32;
212 fn pop_error_scope(&self, index: u32) -> Pin<Box<dyn PopErrorScopeFuture>>;
213
214 unsafe fn start_graphics_debugger_capture(&self);
215 unsafe fn stop_graphics_debugger_capture(&self);
216
217 fn poll(&self, poll_type: wgt::PollType<u64>) -> Result<crate::PollStatus, crate::PollError>;
218
219 fn get_internal_counters(&self) -> crate::InternalCounters;
220 fn generate_allocator_report(&self) -> Option<crate::AllocatorReport>;
221
222 fn destroy(&self);
223}
224
225pub trait QueueInterface: CommonTraits {
226 fn write_buffer(&self, buffer: &DispatchBuffer, offset: crate::BufferAddress, data: &[u8]);
227
228 fn create_staging_buffer(&self, size: crate::BufferSize) -> Option<DispatchQueueWriteBuffer>;
229 fn validate_write_buffer(
230 &self,
231 buffer: &DispatchBuffer,
232 offset: crate::BufferAddress,
233 size: crate::BufferSize,
234 ) -> Option<()>;
235 fn write_staging_buffer(
236 &self,
237 buffer: &DispatchBuffer,
238 offset: crate::BufferAddress,
239 staging_buffer: DispatchQueueWriteBuffer,
240 );
241
242 fn write_texture(
243 &self,
244 texture: crate::TexelCopyTextureInfo<'_>,
245 data: &[u8],
246 data_layout: crate::TexelCopyBufferLayout,
247 size: crate::Extent3d,
248 );
249 #[cfg(web)]
250 fn copy_external_image_to_texture(
251 &self,
252 source: &crate::CopyExternalImageSourceInfo,
253 dest: crate::CopyExternalImageDestInfo<&crate::api::Texture>,
254 size: crate::Extent3d,
255 );
256
257 fn submit(&self, command_buffers: &mut dyn Iterator<Item = DispatchCommandBuffer>) -> u64;
259
260 fn get_timestamp_period(&self) -> f32;
261 fn on_submitted_work_done(&self, callback: BoxSubmittedWorkDoneCallback);
262
263 fn compact_blas(&self, blas: &DispatchBlas) -> (Option<u64>, DispatchBlas);
264
265 fn present(&self, detail: &DispatchSurfaceOutputDetail);
266}
267
268pub trait ShaderModuleInterface: CommonTraits {
269 fn get_compilation_info(&self) -> Pin<Box<dyn ShaderCompilationInfoFuture>>;
270}
271pub trait BindGroupLayoutInterface: CommonTraits {}
272pub trait BindGroupInterface: CommonTraits {}
273pub trait TextureViewInterface: CommonTraits {}
274pub trait SamplerInterface: CommonTraits {}
275pub trait BufferInterface: CommonTraits {
276 fn map_async(
277 &self,
278 mode: crate::MapMode,
279 range: Range<crate::BufferAddress>,
280 callback: BufferMapCallback,
281 );
282 fn get_mapped_range(
283 &self,
284 sub_range: Range<crate::BufferAddress>,
285 ) -> Result<DispatchBufferMappedRange, crate::MapRangeError>;
286
287 fn unmap(&self);
288
289 fn destroy(&self);
290
291 fn size(&self) -> crate::BufferAddress;
292
293 fn usage(&self) -> crate::BufferUsages;
294}
295pub trait TextureInterface: CommonTraits {
296 fn create_view(&self, desc: &crate::TextureViewDescriptor<'_>) -> DispatchTextureView;
297
298 fn destroy(&self);
299
300 fn size(&self) -> wgt::Extent3d;
301
302 fn mip_level_count(&self) -> u32;
303
304 fn sample_count(&self) -> u32;
305
306 fn dimension(&self) -> wgt::TextureDimension;
307
308 fn format(&self) -> wgt::TextureFormat;
309
310 fn usage(&self) -> wgt::TextureUsages;
311
312 unsafe fn mark_externally_initialized(&self) {}
322}
323pub trait ExternalTextureInterface: CommonTraits {
324 fn destroy(&self);
325}
326pub trait BlasInterface: CommonTraits {
327 fn prepare_compact_async(&self, callback: BlasCompactCallback);
328 fn ready_for_compaction(&self) -> bool;
329}
330pub trait TlasInterface: CommonTraits {}
331pub trait QuerySetInterface: CommonTraits {
332 fn destroy(&self);
333
334 fn ty(&self) -> crate::QueryType;
335
336 fn count(&self) -> u32;
337}
338pub trait PipelineLayoutInterface: CommonTraits {}
339pub trait RenderPipelineInterface: CommonTraits {
340 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
341}
342pub trait ComputePipelineInterface: CommonTraits {
343 fn get_bind_group_layout(&self, index: u32) -> DispatchBindGroupLayout;
344}
345pub trait PipelineCacheInterface: CommonTraits {
346 fn get_data(&self) -> Option<Vec<u8>>;
347}
348pub trait CommandEncoderInterface: CommonTraits {
349 fn copy_buffer_to_buffer(
350 &self,
351 source: &DispatchBuffer,
352 source_offset: crate::BufferAddress,
353 destination: &DispatchBuffer,
354 destination_offset: crate::BufferAddress,
355 copy_size: Option<crate::BufferAddress>,
356 );
357 fn copy_buffer_to_texture(
358 &self,
359 source: crate::TexelCopyBufferInfo<'_>,
360 destination: crate::TexelCopyTextureInfo<'_>,
361 copy_size: crate::Extent3d,
362 );
363 fn copy_texture_to_buffer(
364 &self,
365 source: crate::TexelCopyTextureInfo<'_>,
366 destination: crate::TexelCopyBufferInfo<'_>,
367 copy_size: crate::Extent3d,
368 );
369 fn copy_texture_to_texture(
370 &self,
371 source: crate::TexelCopyTextureInfo<'_>,
372 destination: crate::TexelCopyTextureInfo<'_>,
373 copy_size: crate::Extent3d,
374 );
375
376 fn begin_compute_pass(&self, desc: &crate::ComputePassDescriptor<'_>) -> DispatchComputePass;
377 fn begin_render_pass(&self, desc: &crate::RenderPassDescriptor<'_>) -> DispatchRenderPass;
378 fn finish(&mut self) -> DispatchCommandBuffer;
379
380 fn clear_texture(
381 &self,
382 texture: &DispatchTexture,
383 subresource_range: &crate::ImageSubresourceRange,
384 );
385 fn clear_buffer(
386 &self,
387 buffer: &DispatchBuffer,
388 offset: crate::BufferAddress,
389 size: Option<crate::BufferAddress>,
390 );
391
392 fn insert_debug_marker(&self, label: &str);
393 fn push_debug_group(&self, label: &str);
394 fn pop_debug_group(&self);
395
396 fn write_timestamp(&self, query_set: &DispatchQuerySet, query_index: u32);
397 fn resolve_query_set(
398 &self,
399 query_set: &DispatchQuerySet,
400 first_query: u32,
401 query_count: u32,
402 destination: &DispatchBuffer,
403 destination_offset: crate::BufferAddress,
404 );
405 fn mark_acceleration_structures_built<'a>(
406 &self,
407 blas: &mut dyn Iterator<Item = &'a Blas>,
408 tlas: &mut dyn Iterator<Item = &'a Tlas>,
409 );
410
411 fn build_acceleration_structures<'a>(
412 &self,
413 blas: &mut dyn Iterator<Item = &'a crate::BlasBuildEntry<'a>>,
414 tlas: &mut dyn Iterator<Item = &'a crate::Tlas>,
415 );
416
417 fn transition_resources<'a>(
418 &mut self,
419 buffer_transitions: &mut dyn Iterator<Item = wgt::BufferTransition<&'a DispatchBuffer>>,
420 texture_transitions: &mut dyn Iterator<Item = wgt::TextureTransition<&'a DispatchTexture>>,
421 );
422}
423pub trait ComputePassInterface: CommonTraits + Drop {
424 fn set_pipeline(&mut self, pipeline: &DispatchComputePipeline);
425 fn set_bind_group(
426 &mut self,
427 index: u32,
428 bind_group: Option<&DispatchBindGroup>,
429 offsets: &[crate::DynamicOffset],
430 );
431 fn set_immediates(&mut self, offset: u32, data: &[u8]);
432
433 fn insert_debug_marker(&mut self, label: &str);
434 fn push_debug_group(&mut self, group_label: &str);
435 fn pop_debug_group(&mut self);
436
437 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
438 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
439 fn end_pipeline_statistics_query(&mut self);
440
441 fn dispatch_workgroups(&mut self, x: u32, y: u32, z: u32);
442 fn dispatch_workgroups_indirect(
443 &mut self,
444 indirect_buffer: &DispatchBuffer,
445 indirect_offset: crate::BufferAddress,
446 );
447
448 fn transition_resources<'a>(
449 &mut self,
450 buffer_transitions: &mut dyn Iterator<Item = wgt::BufferTransition<&'a DispatchBuffer>>,
451 texture_transitions: &mut dyn Iterator<
452 Item = wgt::TextureTransition<&'a DispatchTextureView>,
453 >,
454 );
455}
456pub trait RenderPassInterface: CommonTraits + Drop {
457 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
458 fn set_bind_group(
459 &mut self,
460 index: u32,
461 bind_group: Option<&DispatchBindGroup>,
462 offsets: &[crate::DynamicOffset],
463 );
464 fn set_index_buffer(
465 &mut self,
466 buffer: &DispatchBuffer,
467 index_format: crate::IndexFormat,
468 offset: crate::BufferAddress,
469 size: Option<crate::BufferAddress>,
470 );
471 fn set_vertex_buffer(
472 &mut self,
473 slot: u32,
474 buffer: Option<&DispatchBuffer>,
475 offset: crate::BufferAddress,
476 size: Option<crate::BufferAddress>,
477 );
478 fn set_immediates(&mut self, offset: u32, data: &[u8]);
479 fn set_blend_constant(&mut self, color: crate::Color);
480 fn set_scissor_rect(&mut self, x: u32, y: u32, width: u32, height: u32);
481 fn set_viewport(
482 &mut self,
483 x: f32,
484 y: f32,
485 width: f32,
486 height: f32,
487 min_depth: f32,
488 max_depth: f32,
489 );
490 fn set_stencil_reference(&mut self, reference: u32);
491
492 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
493 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
494 fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32);
495 fn draw_indirect(
496 &mut self,
497 indirect_buffer: &DispatchBuffer,
498 indirect_offset: crate::BufferAddress,
499 );
500 fn draw_indexed_indirect(
501 &mut self,
502 indirect_buffer: &DispatchBuffer,
503 indirect_offset: crate::BufferAddress,
504 );
505 fn draw_mesh_tasks_indirect(
506 &mut self,
507 indirect_buffer: &DispatchBuffer,
508 indirect_offset: crate::BufferAddress,
509 );
510
511 fn multi_draw_indirect(
512 &mut self,
513 indirect_buffer: &DispatchBuffer,
514 indirect_offset: crate::BufferAddress,
515 count: u32,
516 );
517 fn multi_draw_indexed_indirect(
518 &mut self,
519 indirect_buffer: &DispatchBuffer,
520 indirect_offset: crate::BufferAddress,
521 count: u32,
522 );
523 fn multi_draw_indirect_count(
524 &mut self,
525 indirect_buffer: &DispatchBuffer,
526 indirect_offset: crate::BufferAddress,
527 count_buffer: &DispatchBuffer,
528 count_buffer_offset: crate::BufferAddress,
529 max_count: u32,
530 );
531 fn multi_draw_mesh_tasks_indirect(
532 &mut self,
533 indirect_buffer: &DispatchBuffer,
534 indirect_offset: crate::BufferAddress,
535 count: u32,
536 );
537 fn multi_draw_indexed_indirect_count(
538 &mut self,
539 indirect_buffer: &DispatchBuffer,
540 indirect_offset: crate::BufferAddress,
541 count_buffer: &DispatchBuffer,
542 count_buffer_offset: crate::BufferAddress,
543 max_count: u32,
544 );
545 fn multi_draw_mesh_tasks_indirect_count(
546 &mut self,
547 indirect_buffer: &DispatchBuffer,
548 indirect_offset: crate::BufferAddress,
549 count_buffer: &DispatchBuffer,
550 count_buffer_offset: crate::BufferAddress,
551 max_count: u32,
552 );
553
554 fn insert_debug_marker(&mut self, label: &str);
555 fn push_debug_group(&mut self, group_label: &str);
556 fn pop_debug_group(&mut self);
557
558 fn write_timestamp(&mut self, query_set: &DispatchQuerySet, query_index: u32);
559 fn begin_occlusion_query(&mut self, query_index: u32);
560 fn end_occlusion_query(&mut self);
561 fn begin_pipeline_statistics_query(&mut self, query_set: &DispatchQuerySet, query_index: u32);
562 fn end_pipeline_statistics_query(&mut self);
563
564 fn execute_bundles(&mut self, render_bundles: &mut dyn Iterator<Item = &DispatchRenderBundle>);
565}
566
567pub trait RenderBundleEncoderInterface: CommonTraits {
568 fn set_pipeline(&mut self, pipeline: &DispatchRenderPipeline);
569 fn set_bind_group(
570 &mut self,
571 index: u32,
572 bind_group: Option<&DispatchBindGroup>,
573 offsets: &[crate::DynamicOffset],
574 );
575 fn set_index_buffer(
576 &mut self,
577 buffer: &DispatchBuffer,
578 index_format: crate::IndexFormat,
579 offset: crate::BufferAddress,
580 size: Option<crate::BufferAddress>,
581 );
582 fn set_vertex_buffer(
583 &mut self,
584 slot: u32,
585 buffer: Option<&DispatchBuffer>,
586 offset: crate::BufferAddress,
587 size: Option<crate::BufferAddress>,
588 );
589 fn set_immediates(&mut self, offset: u32, data: &[u8]);
590
591 fn insert_debug_marker(&mut self, label: &str);
592 fn push_debug_group(&mut self, group_label: &str);
593 fn pop_debug_group(&mut self);
594
595 fn draw(&mut self, vertices: Range<u32>, instances: Range<u32>);
596 fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
597 fn draw_indirect(
598 &mut self,
599 indirect_buffer: &DispatchBuffer,
600 indirect_offset: crate::BufferAddress,
601 );
602 fn draw_indexed_indirect(
603 &mut self,
604 indirect_buffer: &DispatchBuffer,
605 indirect_offset: crate::BufferAddress,
606 );
607
608 fn finish(self, desc: &crate::RenderBundleDescriptor<'_>) -> DispatchRenderBundle
609 where
610 Self: Sized;
611
612 #[cfg(custom)]
623 fn finish_boxed(
624 self: Box<Self>,
625 desc: &crate::RenderBundleDescriptor<'_>,
626 ) -> DispatchRenderBundle;
627}
628
629pub trait CommandBufferInterface: CommonTraits {}
630pub trait RenderBundleInterface: CommonTraits {}
631
632pub trait SurfaceInterface: CommonTraits {
633 fn get_capabilities(&self, adapter: &DispatchAdapter) -> crate::SurfaceCapabilities;
634
635 fn display_hdr_info(&self, adapter: &DispatchAdapter) -> crate::DisplayHdrInfo {
640 let _ = adapter;
641 crate::DisplayHdrInfo::default()
642 }
643
644 fn configure(&self, device: &DispatchDevice, config: &crate::SurfaceConfiguration);
645 fn get_current_texture(
646 &self,
647 desc: Option<crate::TextureDescriptor<'static>>,
648 ) -> (
649 Option<DispatchTexture>,
650 crate::SurfaceStatus,
651 DispatchSurfaceOutputDetail,
652 );
653}
654
655pub trait SurfaceOutputDetailInterface: CommonTraits {
656 fn texture_discard(&self);
657 fn texture_release(&self);
658}
659
660pub trait QueueWriteBufferInterface: CommonTraits {
661 fn len(&self) -> usize;
662
663 unsafe fn write_slice(&mut self) -> WriteOnly<'_, [u8]>;
667}
668
669pub trait BufferMappedRangeInterface: CommonTraits {
670 #[cfg_attr(not(wgpu_core), expect(unused))]
672 fn len(&self) -> usize;
673
674 unsafe fn read_slice(&self) -> &[u8];
678
679 unsafe fn write_slice(&mut self) -> WriteOnly<'_, [u8]>;
683
684 #[cfg(webgpu)]
685 fn as_uint8array(&self) -> &js_sys::Uint8Array;
686}
687
688macro_rules! explicit_send_sync_impl {
690 ($name:ident) => {
691 #[cfg(send_sync)]
706 const _: () = {
707 unsafe impl Send for $name {}
709 unsafe impl Sync for $name {}
711
712 fn _fields_are_send_sync(dispatch_enum: &$name) {
719 fn _check_bound<T: Send + Sync>(_: &T) {}
720 match *dispatch_enum {
722 #[cfg(wgpu_core)]
723 $name::Core(ref value) => _check_bound(value),
724 #[cfg(webgpu)]
725 $name::WebGPU(ref value) => _check_bound(value),
726 #[cfg(custom)]
727 $name::Custom(ref value) => _check_bound(value),
728 }
729 }
730 };
731 };
732}
733
734macro_rules! dispatch_types {
805 (
806 ref type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
807 ) => {
808 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
809 pub enum $name {
810 #[cfg(wgpu_core)]
811 Core($core_type),
812 #[cfg(webgpu)]
813 WebGPU($webgpu_type),
814 #[allow(clippy::allow_attributes, private_interfaces)]
815 #[cfg(custom)]
816 Custom($custom_type),
817 }
818
819 impl $name {
820 #[cfg(wgpu_core)]
821 #[inline]
822 #[allow(clippy::allow_attributes, unused)]
823 pub fn as_core(&self) -> &$core_type {
824 match self {
825 Self::Core(value) => value,
826 _ => panic!(concat!(stringify!($name), " is not core")),
827 }
828 }
829
830 #[cfg(wgpu_core)]
831 #[inline]
832 #[allow(clippy::allow_attributes, unused)]
833 pub fn as_core_opt(&self) -> Option<&$core_type> {
834 match self {
835 Self::Core(value) => Some(value),
836 _ => None,
837 }
838 }
839
840 #[cfg(custom)]
841 #[inline]
842 #[allow(clippy::allow_attributes, unused)]
843 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
844 match self {
845 Self::Custom(value) => value.downcast(),
846 _ => None,
847 }
848 }
849
850 #[cfg(webgpu)]
851 #[inline]
852 #[allow(clippy::allow_attributes, unused)]
853 pub fn as_webgpu(&self) -> &$webgpu_type {
854 match self {
855 Self::WebGPU(value) => value,
856 _ => panic!(concat!(stringify!($name), " is not webgpu")),
857 }
858 }
859
860 #[cfg(webgpu)]
861 #[inline]
862 #[allow(clippy::allow_attributes, unused)]
863 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
864 match self {
865 Self::WebGPU(value) => Some(value),
866 _ => None,
867 }
868 }
869
870 #[cfg(custom)]
871 #[inline]
872 pub fn custom<T: $interface>(t: T) -> Self {
873 Self::Custom($custom_type::new(t))
874 }
875 }
876
877 #[cfg(wgpu_core)]
878 impl From<$core_type> for $name {
879 #[inline]
880 fn from(value: $core_type) -> Self {
881 Self::Core(value)
882 }
883 }
884
885 #[cfg(webgpu)]
886 impl From<$webgpu_type> for $name {
887 #[inline]
888 fn from(value: $webgpu_type) -> Self {
889 Self::WebGPU(value)
890 }
891 }
892
893 impl core::ops::Deref for $name {
894 type Target = dyn $interface;
895
896 #[inline]
897 fn deref(&self) -> &Self::Target {
898 match self {
899 #[cfg(wgpu_core)]
900 Self::Core(value) => value,
901 #[cfg(webgpu)]
902 Self::WebGPU(value) => value,
903 #[cfg(custom)]
904 Self::Custom(value) => value.deref(),
905 #[cfg(not(any(wgpu_core, webgpu)))]
906 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
907 }
908 }
909 }
910
911 explicit_send_sync_impl!($name);
912 };
913 (
914 mut type $name:ident: $interface:ident = $core_type:ident,$webgpu_type:ident,$custom_type:ident
915 ) => {
916 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
917 pub enum $name {
918 #[cfg(wgpu_core)]
919 Core($core_type),
920 #[cfg(webgpu)]
921 WebGPU($webgpu_type),
922 #[allow(clippy::allow_attributes, private_interfaces)]
923 #[cfg(custom)]
924 Custom($custom_type),
925 }
926
927 impl $name {
928 #[cfg(wgpu_core)]
929 #[inline]
930 #[allow(clippy::allow_attributes, unused)]
931 pub fn as_core(&self) -> &$core_type {
932 match self {
933 Self::Core(value) => value,
934 _ => panic!(concat!(stringify!($name), " is not core")),
935 }
936 }
937
938 #[cfg(wgpu_core)]
939 #[inline]
940 #[allow(clippy::allow_attributes, unused)]
941 pub fn as_core_mut(&mut self) -> &mut $core_type {
942 match self {
943 Self::Core(value) => value,
944 _ => panic!(concat!(stringify!($name), " is not core")),
945 }
946 }
947
948 #[cfg(wgpu_core)]
949 #[inline]
950 #[allow(clippy::allow_attributes, unused)]
951 pub fn as_core_opt(&self) -> Option<&$core_type> {
952 match self {
953 Self::Core(value) => Some(value),
954 _ => None,
955 }
956 }
957
958 #[cfg(wgpu_core)]
959 #[inline]
960 #[allow(clippy::allow_attributes, unused)]
961 pub fn as_core_mut_opt(
962 &mut self,
963 ) -> Option<&mut $core_type> {
964 match self {
965 Self::Core(value) => Some(value),
966 _ => None,
967 }
968 }
969
970 #[cfg(custom)]
971 #[inline]
972 #[allow(clippy::allow_attributes, unused)]
973 pub fn as_custom<T: $interface>(&self) -> Option<&T> {
974 match self {
975 Self::Custom(value) => value.downcast(),
976 _ => None,
977 }
978 }
979
980 #[cfg(webgpu)]
981 #[inline]
982 #[allow(clippy::allow_attributes, unused)]
983 pub fn as_webgpu(&self) -> &$webgpu_type {
984 match self {
985 Self::WebGPU(value) => value,
986 _ => panic!(concat!(stringify!($name), " is not webgpu")),
987 }
988 }
989
990 #[cfg(webgpu)]
991 #[inline]
992 #[allow(clippy::allow_attributes, unused)]
993 pub fn as_webgpu_mut(&mut self) -> &mut $webgpu_type {
994 match self {
995 Self::WebGPU(value) => value,
996 _ => panic!(concat!(stringify!($name), " is not webgpu")),
997 }
998 }
999
1000 #[cfg(webgpu)]
1001 #[inline]
1002 #[allow(clippy::allow_attributes, unused)]
1003 pub fn as_webgpu_opt(&self) -> Option<&$webgpu_type> {
1004 match self {
1005 Self::WebGPU(value) => Some(value),
1006 _ => None,
1007 }
1008 }
1009
1010 #[cfg(webgpu)]
1011 #[inline]
1012 #[allow(clippy::allow_attributes, unused)]
1013 pub fn as_webgpu_mut_opt(
1014 &mut self,
1015 ) -> Option<&mut $webgpu_type> {
1016 match self {
1017 Self::WebGPU(value) => Some(value),
1018 _ => None,
1019 }
1020 }
1021
1022 #[cfg(custom)]
1023 #[inline]
1024 pub fn custom<T: $interface>(t: T) -> Self {
1025 Self::Custom($custom_type::new(t))
1026 }
1027 }
1028
1029 #[cfg(wgpu_core)]
1030 impl From<$core_type> for $name {
1031 #[inline]
1032 fn from(value: $core_type) -> Self {
1033 Self::Core(value)
1034 }
1035 }
1036
1037 #[cfg(webgpu)]
1038 impl From<$webgpu_type> for $name {
1039 #[inline]
1040 fn from(value: $webgpu_type) -> Self {
1041 Self::WebGPU(value)
1042 }
1043 }
1044
1045 impl core::ops::Deref for $name {
1046 type Target = dyn $interface;
1047
1048 #[inline]
1049 fn deref(&self) -> &Self::Target {
1050 match self {
1051 #[cfg(wgpu_core)]
1052 Self::Core(value) => value,
1053 #[cfg(webgpu)]
1054 Self::WebGPU(value) => value,
1055 #[cfg(custom)]
1056 Self::Custom(value) => value.deref(),
1057 #[cfg(not(any(wgpu_core, webgpu)))]
1058 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
1059 }
1060 }
1061 }
1062
1063 impl core::ops::DerefMut for $name {
1064 #[inline]
1065 fn deref_mut(&mut self) -> &mut Self::Target {
1066 match self {
1067 #[cfg(wgpu_core)]
1068 Self::Core(value) => value,
1069 #[cfg(webgpu)]
1070 Self::WebGPU(value) => value,
1071 #[cfg(custom)]
1072 Self::Custom(value) => value.deref_mut(),
1073 #[cfg(not(any(wgpu_core, webgpu)))]
1074 _ => panic!("No context available. You need to enable one of wgpu's backend feature build flags."),
1075 }
1076 }
1077 }
1078
1079 explicit_send_sync_impl!($name);
1080 };
1081}
1082
1083dispatch_types! {ref type DispatchInstance: InstanceInterface = ContextWgpuCore, ContextWebGpu, DynContext}
1084dispatch_types! {ref type DispatchAdapter: AdapterInterface = CoreAdapter, WebAdapter, DynAdapter}
1085dispatch_types! {ref type DispatchDevice: DeviceInterface = CoreDevice, WebDevice, DynDevice}
1086dispatch_types! {ref type DispatchQueue: QueueInterface = CoreQueue, WebQueue, DynQueue}
1087dispatch_types! {ref type DispatchShaderModule: ShaderModuleInterface = CoreShaderModule, WebShaderModule, DynShaderModule}
1088dispatch_types! {ref type DispatchBindGroupLayout: BindGroupLayoutInterface = CoreBindGroupLayout, WebBindGroupLayout, DynBindGroupLayout}
1089dispatch_types! {ref type DispatchBindGroup: BindGroupInterface = CoreBindGroup, WebBindGroup, DynBindGroup}
1090dispatch_types! {ref type DispatchTextureView: TextureViewInterface = CoreTextureView, WebTextureView, DynTextureView}
1091dispatch_types! {ref type DispatchSampler: SamplerInterface = CoreSampler, WebSampler, DynSampler}
1092dispatch_types! {ref type DispatchBuffer: BufferInterface = CoreBuffer, WebBuffer, DynBuffer}
1093dispatch_types! {ref type DispatchTexture: TextureInterface = CoreTexture, WebTexture, DynTexture}
1094dispatch_types! {ref type DispatchExternalTexture: ExternalTextureInterface = CoreExternalTexture, WebExternalTexture, DynExternalTexture}
1095dispatch_types! {ref type DispatchBlas: BlasInterface = CoreBlas, WebBlas, DynBlas}
1096dispatch_types! {ref type DispatchTlas: TlasInterface = CoreTlas, WebTlas, DynTlas}
1097dispatch_types! {ref type DispatchQuerySet: QuerySetInterface = CoreQuerySet, WebQuerySet, DynQuerySet}
1098dispatch_types! {ref type DispatchPipelineLayout: PipelineLayoutInterface = CorePipelineLayout, WebPipelineLayout, DynPipelineLayout}
1099dispatch_types! {ref type DispatchRenderPipeline: RenderPipelineInterface = CoreRenderPipeline, WebRenderPipeline, DynRenderPipeline}
1100dispatch_types! {ref type DispatchComputePipeline: ComputePipelineInterface = CoreComputePipeline, WebComputePipeline, DynComputePipeline}
1101dispatch_types! {ref type DispatchPipelineCache: PipelineCacheInterface = CorePipelineCache, WebPipelineCache, DynPipelineCache}
1102dispatch_types! {mut type DispatchCommandEncoder: CommandEncoderInterface = CoreCommandEncoder, WebCommandEncoder, DynCommandEncoder}
1103dispatch_types! {mut type DispatchComputePass: ComputePassInterface = CoreComputePass, WebComputePassEncoder, DynComputePass}
1104dispatch_types! {mut type DispatchRenderPass: RenderPassInterface = CoreRenderPass, WebRenderPassEncoder, DynRenderPass}
1105dispatch_types! {mut type DispatchCommandBuffer: CommandBufferInterface = CoreCommandBuffer, WebCommandBuffer, DynCommandBuffer}
1106dispatch_types! {mut type DispatchRenderBundleEncoder: RenderBundleEncoderInterface = CoreRenderBundleEncoder, WebRenderBundleEncoder, DynRenderBundleEncoder}
1107dispatch_types! {ref type DispatchRenderBundle: RenderBundleInterface = CoreRenderBundle, WebRenderBundle, DynRenderBundle}
1108dispatch_types! {ref type DispatchSurface: SurfaceInterface = CoreSurface, WebSurface, DynSurface}
1109dispatch_types! {ref type DispatchSurfaceOutputDetail: SurfaceOutputDetailInterface = CoreSurfaceOutputDetail, WebSurfaceOutputDetail, DynSurfaceOutputDetail}
1110dispatch_types! {mut type DispatchQueueWriteBuffer: QueueWriteBufferInterface = CoreQueueWriteBuffer, WebQueueWriteBuffer, DynQueueWriteBuffer}
1111dispatch_types! {mut type DispatchBufferMappedRange: BufferMappedRangeInterface = CoreBufferMappedRange, WebBufferMappedRange, DynBufferMappedRange}