1#![allow(ambiguous_wide_pointer_comparisons)]
4
5pub use crate::dispatch::*;
6
7use crate::cmp::AtomicU64;
8use alloc::boxed::Box;
9use alloc::sync::Arc;
10use core::sync::atomic::Ordering;
11
12macro_rules! dyn_type {
13 (pub mut struct $name:ident(dyn $interface:tt)) => {
16 #[derive(Debug)]
17 pub(crate) struct $name(Arc<dyn $interface>);
18 crate::cmp::impl_eq_ord_hash_arc_address!($name => .0);
19
20 impl $name {
21 pub(crate) fn new<T: $interface>(t: T) -> Self {
22 Self(Arc::new(t))
23 }
24
25 #[allow(clippy::allow_attributes, dead_code)]
26 pub(crate) fn downcast<T: $interface>(&self) -> Option<&T> {
27 self.0.as_ref().as_any().downcast_ref()
28 }
29 }
30
31 impl core::ops::Deref for $name {
32 type Target = dyn $interface;
33
34 #[inline]
35 fn deref(&self) -> &Self::Target {
36 self.0.as_ref()
37 }
38 }
39
40 impl core::ops::DerefMut for $name {
41 #[inline]
42 fn deref_mut(&mut self) -> &mut Self::Target {
43 Arc::get_mut(&mut self.0).expect("")
44 }
45 }
46 };
47 (pub ref struct $name:ident(dyn $interface:tt)) => {
49 #[derive(Debug, Clone)]
50 pub(crate) struct $name(Arc<dyn $interface>);
51 crate::cmp::impl_eq_ord_hash_arc_address!($name => .0);
52
53 impl $name {
54 pub(crate) fn new<T: $interface>(t: T) -> Self {
55 Self(Arc::new(t))
56 }
57
58 pub(crate) fn downcast<T: $interface>(&self) -> Option<&T> {
59 self.0.as_ref().as_any().downcast_ref()
60 }
61 }
62
63 impl core::ops::Deref for $name {
64 type Target = dyn $interface;
65
66 #[inline]
67 fn deref(&self) -> &Self::Target {
68 self.0.as_ref()
69 }
70 }
71 };
72}
73
74dyn_type!(pub ref struct DynContext(dyn InstanceInterface));
75dyn_type!(pub ref struct DynAdapter(dyn AdapterInterface));
76dyn_type!(pub ref struct DynDevice(dyn DeviceInterface));
77dyn_type!(pub ref struct DynQueue(dyn QueueInterface));
78dyn_type!(pub ref struct DynShaderModule(dyn ShaderModuleInterface));
79dyn_type!(pub ref struct DynBindGroupLayout(dyn BindGroupLayoutInterface));
80dyn_type!(pub ref struct DynBindGroup(dyn BindGroupInterface));
81dyn_type!(pub ref struct DynTextureView(dyn TextureViewInterface));
82dyn_type!(pub ref struct DynSampler(dyn SamplerInterface));
83dyn_type!(pub ref struct DynBuffer(dyn BufferInterface));
84dyn_type!(pub ref struct DynTexture(dyn TextureInterface));
85dyn_type!(pub ref struct DynExternalTexture(dyn ExternalTextureInterface));
86dyn_type!(pub ref struct DynBlas(dyn BlasInterface));
87dyn_type!(pub ref struct DynTlas(dyn TlasInterface));
88dyn_type!(pub ref struct DynQuerySet(dyn QuerySetInterface));
89dyn_type!(pub ref struct DynPipelineLayout(dyn PipelineLayoutInterface));
90dyn_type!(pub ref struct DynRenderPipeline(dyn RenderPipelineInterface));
91dyn_type!(pub ref struct DynComputePipeline(dyn ComputePipelineInterface));
92dyn_type!(pub ref struct DynPipelineCache(dyn PipelineCacheInterface));
93dyn_type!(pub mut struct DynCommandEncoder(dyn CommandEncoderInterface));
94dyn_type!(pub mut struct DynComputePass(dyn ComputePassInterface));
95dyn_type!(pub mut struct DynRenderPass(dyn RenderPassInterface));
96dyn_type!(pub mut struct DynCommandBuffer(dyn CommandBufferInterface));
97
98static NEXT_RENDER_BUNDLE_ENCODER_ID: AtomicU64 = AtomicU64::new(0);
99
100#[derive(Debug)]
103pub(crate) struct DynRenderBundleEncoder {
104 id: u64,
107 inner: Box<dyn RenderBundleEncoderInterface>,
108}
109
110impl DynRenderBundleEncoder {
111 pub(crate) fn new<T: RenderBundleEncoderInterface>(t: T) -> Self {
112 Self {
113 id: NEXT_RENDER_BUNDLE_ENCODER_ID.fetch_add(1, Ordering::Relaxed),
114 inner: Box::new(t),
115 }
116 }
117
118 pub(crate) fn downcast<T: RenderBundleEncoderInterface>(&self) -> Option<&T> {
119 self.inner.as_ref().as_any().downcast_ref()
120 }
121
122 pub(crate) fn finish_boxed(
123 self,
124 desc: &crate::RenderBundleDescriptor<'_>,
125 ) -> crate::dispatch::DispatchRenderBundle {
126 self.inner.finish_boxed(desc)
127 }
128}
129
130impl core::ops::Deref for DynRenderBundleEncoder {
131 type Target = dyn RenderBundleEncoderInterface;
132 #[inline]
133 fn deref(&self) -> &Self::Target {
134 self.inner.as_ref()
135 }
136}
137
138impl core::ops::DerefMut for DynRenderBundleEncoder {
139 #[inline]
140 fn deref_mut(&mut self) -> &mut Self::Target {
141 self.inner.as_mut()
142 }
143}
144
145impl PartialEq for DynRenderBundleEncoder {
150 fn eq(&self, other: &Self) -> bool {
151 self.id == other.id
152 }
153}
154impl Eq for DynRenderBundleEncoder {}
155
156impl PartialOrd for DynRenderBundleEncoder {
157 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
158 Some(self.cmp(other))
159 }
160}
161impl Ord for DynRenderBundleEncoder {
162 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
163 self.id.cmp(&other.id)
164 }
165}
166
167impl core::hash::Hash for DynRenderBundleEncoder {
168 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
169 self.id.hash(state);
170 }
171}
172
173dyn_type!(pub ref struct DynRenderBundle(dyn RenderBundleInterface));
174dyn_type!(pub ref struct DynSurface(dyn SurfaceInterface));
175dyn_type!(pub ref struct DynSurfaceOutputDetail(dyn SurfaceOutputDetailInterface));
176dyn_type!(pub mut struct DynQueueWriteBuffer(dyn QueueWriteBufferInterface));
177dyn_type!(pub mut struct DynBufferMappedRange(dyn BufferMappedRangeInterface));