Skip to main content

wgpu_hal/dynamic/
device.rs

1use alloc::{borrow::ToOwned as _, boxed::Box, vec::Vec};
2
3use crate::{
4    AccelerationStructureBuildSizes, AccelerationStructureDescriptor, Api, BindGroupDescriptor,
5    BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor,
6    ComputePipelineDescriptor, Device, DeviceError, FenceValue,
7    GetAccelerationStructureBuildSizesDescriptor, Label, MemoryRange, PipelineCacheDescriptor,
8    PipelineCacheError, PipelineError, PipelineLayoutDescriptor, RayObjectIntersectionState,
9    RayTracingPipelineDescriptor, RenderPipelineDescriptor, SamplerDescriptor, ShaderError,
10    ShaderInput, ShaderModuleDescriptor, TextureDescriptor, TextureViewDescriptor, TlasInstance,
11};
12
13use super::{
14    DynAccelerationStructure, DynBindGroup, DynBindGroupLayout, DynBuffer, DynCommandEncoder,
15    DynComputePipeline, DynFence, DynPipelineCache, DynPipelineLayout, DynQuerySet, DynQueue,
16    DynRayTracingPipeline, DynRenderPipeline, DynResource, DynResourceExt as _, DynSampler,
17    DynShaderModule, DynTexture, DynTextureView,
18};
19
20pub trait DynDevice: DynResource {
21    unsafe fn create_buffer(
22        &self,
23        desc: &BufferDescriptor,
24    ) -> Result<Box<dyn DynBuffer>, DeviceError>;
25
26    unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>);
27    unsafe fn add_raw_buffer(&self, buffer: &dyn DynBuffer);
28
29    unsafe fn map_buffer(
30        &self,
31        buffer: &dyn DynBuffer,
32        range: MemoryRange,
33    ) -> Result<BufferMapping, DeviceError>;
34
35    unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer);
36
37    unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]);
38    unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]);
39
40    unsafe fn create_texture(
41        &self,
42        desc: &TextureDescriptor,
43    ) -> Result<Box<dyn DynTexture>, DeviceError>;
44    unsafe fn destroy_texture(&self, texture: Box<dyn DynTexture>);
45    unsafe fn add_raw_texture(&self, texture: &dyn DynTexture);
46
47    unsafe fn create_texture_view(
48        &self,
49        texture: &dyn DynTexture,
50        desc: &TextureViewDescriptor,
51    ) -> Result<Box<dyn DynTextureView>, DeviceError>;
52    unsafe fn destroy_texture_view(&self, view: Box<dyn DynTextureView>);
53    unsafe fn create_sampler(
54        &self,
55        desc: &SamplerDescriptor,
56    ) -> Result<Box<dyn DynSampler>, DeviceError>;
57    unsafe fn destroy_sampler(&self, sampler: Box<dyn DynSampler>);
58
59    unsafe fn create_command_encoder(
60        &self,
61        desc: &CommandEncoderDescriptor<dyn DynQueue>,
62    ) -> Result<Box<dyn DynCommandEncoder>, DeviceError>;
63
64    unsafe fn create_bind_group_layout(
65        &self,
66        desc: &BindGroupLayoutDescriptor,
67    ) -> Result<Box<dyn DynBindGroupLayout>, DeviceError>;
68    unsafe fn destroy_bind_group_layout(&self, bg_layout: Box<dyn DynBindGroupLayout>);
69
70    unsafe fn create_pipeline_layout(
71        &self,
72        desc: &PipelineLayoutDescriptor<dyn DynBindGroupLayout>,
73    ) -> Result<Box<dyn DynPipelineLayout>, DeviceError>;
74    unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box<dyn DynPipelineLayout>);
75
76    unsafe fn create_bind_group(
77        &self,
78        desc: &BindGroupDescriptor<
79            dyn DynBindGroupLayout,
80            dyn DynBuffer,
81            dyn DynSampler,
82            dyn DynTextureView,
83            dyn DynAccelerationStructure,
84        >,
85    ) -> Result<Box<dyn DynBindGroup>, DeviceError>;
86    unsafe fn destroy_bind_group(&self, group: Box<dyn DynBindGroup>);
87
88    unsafe fn create_shader_module(
89        &self,
90        desc: &ShaderModuleDescriptor,
91        shader: ShaderInput,
92    ) -> Result<Box<dyn DynShaderModule>, ShaderError>;
93    unsafe fn destroy_shader_module(&self, module: Box<dyn DynShaderModule>);
94
95    unsafe fn create_render_pipeline(
96        &self,
97        desc: &RenderPipelineDescriptor<
98            dyn DynPipelineLayout,
99            dyn DynShaderModule,
100            dyn DynPipelineCache,
101        >,
102    ) -> Result<Box<dyn DynRenderPipeline>, PipelineError>;
103    unsafe fn destroy_render_pipeline(&self, pipeline: Box<dyn DynRenderPipeline>);
104
105    unsafe fn create_compute_pipeline(
106        &self,
107        desc: &ComputePipelineDescriptor<
108            dyn DynPipelineLayout,
109            dyn DynShaderModule,
110            dyn DynPipelineCache,
111        >,
112    ) -> Result<Box<dyn DynComputePipeline>, PipelineError>;
113    unsafe fn destroy_compute_pipeline(&self, pipeline: Box<dyn DynComputePipeline>);
114
115    unsafe fn create_ray_tracing_pipeline(
116        &self,
117        desc: &RayTracingPipelineDescriptor<
118            dyn DynPipelineLayout,
119            dyn DynShaderModule,
120            dyn DynPipelineCache,
121        >,
122    ) -> Result<Box<dyn DynRayTracingPipeline>, PipelineError>;
123    unsafe fn destroy_ray_tracing_pipeline(&self, pipeline: Box<dyn DynRayTracingPipeline>);
124    unsafe fn get_raytracing_pipeline_group_data(
125        &self,
126        pipeline: &dyn DynRayTracingPipeline,
127        groups: core::ops::Range<u32>,
128    ) -> Result<Vec<u8>, DeviceError>;
129
130    unsafe fn create_pipeline_cache(
131        &self,
132        desc: &PipelineCacheDescriptor<'_>,
133    ) -> Result<Box<dyn DynPipelineCache>, PipelineCacheError>;
134    fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> {
135        None
136    }
137    unsafe fn destroy_pipeline_cache(&self, cache: Box<dyn DynPipelineCache>);
138
139    unsafe fn create_query_set(
140        &self,
141        desc: &wgt::QuerySetDescriptor<Label>,
142    ) -> Result<Box<dyn DynQuerySet>, DeviceError>;
143    unsafe fn destroy_query_set(&self, set: Box<dyn DynQuerySet>);
144
145    unsafe fn create_fence(&self) -> Result<Box<dyn DynFence>, DeviceError>;
146    unsafe fn destroy_fence(&self, fence: Box<dyn DynFence>);
147    unsafe fn get_fence_value(&self, fence: &dyn DynFence) -> Result<FenceValue, DeviceError>;
148
149    unsafe fn wait(
150        &self,
151        fence: &dyn DynFence,
152        value: FenceValue,
153        timeout: Option<core::time::Duration>,
154    ) -> Result<bool, DeviceError>;
155
156    unsafe fn start_graphics_debugger_capture(&self) -> bool;
157    unsafe fn stop_graphics_debugger_capture(&self);
158
159    unsafe fn pipeline_cache_get_data(&self, cache: &dyn DynPipelineCache) -> Option<Vec<u8>>;
160
161    unsafe fn create_acceleration_structure(
162        &self,
163        desc: &AccelerationStructureDescriptor,
164    ) -> Result<Box<dyn DynAccelerationStructure>, DeviceError>;
165    unsafe fn get_acceleration_structure_build_sizes(
166        &self,
167        desc: &GetAccelerationStructureBuildSizesDescriptor<dyn DynBuffer>,
168    ) -> AccelerationStructureBuildSizes;
169    unsafe fn get_acceleration_structure_device_address(
170        &self,
171        acceleration_structure: &dyn DynAccelerationStructure,
172    ) -> wgt::BufferAddress;
173    unsafe fn destroy_acceleration_structure(
174        &self,
175        acceleration_structure: Box<dyn DynAccelerationStructure>,
176    );
177    fn tlas_instance_to_bytes(&self, instance: TlasInstance) -> Vec<u8>;
178
179    fn get_internal_counters(&self) -> wgt::HalCounters;
180    fn generate_allocator_report(&self) -> Option<wgt::AllocatorReport>;
181
182    fn check_if_oom(&self) -> Result<(), DeviceError>;
183}
184
185impl<D: Device + DynResource> DynDevice for D {
186    unsafe fn create_buffer(
187        &self,
188        desc: &BufferDescriptor,
189    ) -> Result<Box<dyn DynBuffer>, DeviceError> {
190        unsafe { D::create_buffer(self, desc) }.map(|b| -> Box<dyn DynBuffer> { Box::new(b) })
191    }
192
193    unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>) {
194        unsafe { D::destroy_buffer(self, buffer.unbox()) };
195    }
196    unsafe fn add_raw_buffer(&self, buffer: &dyn DynBuffer) {
197        let buffer = buffer.expect_downcast_ref();
198        unsafe { D::add_raw_buffer(self, buffer) };
199    }
200
201    unsafe fn map_buffer(
202        &self,
203        buffer: &dyn DynBuffer,
204        range: MemoryRange,
205    ) -> Result<BufferMapping, DeviceError> {
206        let buffer = buffer.expect_downcast_ref();
207        unsafe { D::map_buffer(self, buffer, range) }
208    }
209
210    unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer) {
211        let buffer = buffer.expect_downcast_ref();
212        unsafe { D::unmap_buffer(self, buffer) }
213    }
214
215    unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
216        let buffer = buffer.expect_downcast_ref();
217        unsafe { D::flush_mapped_ranges(self, buffer, ranges.iter().cloned()) }
218    }
219
220    unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
221        let buffer = buffer.expect_downcast_ref();
222        unsafe { D::invalidate_mapped_ranges(self, buffer, ranges.iter().cloned()) }
223    }
224
225    unsafe fn create_texture(
226        &self,
227        desc: &TextureDescriptor,
228    ) -> Result<Box<dyn DynTexture>, DeviceError> {
229        unsafe { D::create_texture(self, desc) }.map(|b| {
230            let boxed_texture: Box<<D::A as Api>::Texture> = Box::new(b);
231            let boxed_texture: Box<dyn DynTexture> = boxed_texture;
232            boxed_texture
233        })
234    }
235
236    unsafe fn destroy_texture(&self, texture: Box<dyn DynTexture>) {
237        unsafe { D::destroy_texture(self, texture.unbox()) };
238    }
239
240    unsafe fn add_raw_texture(&self, texture: &dyn DynTexture) {
241        let texture = texture.expect_downcast_ref();
242        unsafe { D::add_raw_texture(self, texture) };
243    }
244
245    unsafe fn create_texture_view(
246        &self,
247        texture: &dyn DynTexture,
248        desc: &TextureViewDescriptor,
249    ) -> Result<Box<dyn DynTextureView>, DeviceError> {
250        let texture = texture.expect_downcast_ref();
251        unsafe { D::create_texture_view(self, texture, desc) }.map(|b| {
252            let boxed_texture_view: Box<<D::A as Api>::TextureView> = Box::new(b);
253            let boxed_texture_view: Box<dyn DynTextureView> = boxed_texture_view;
254            boxed_texture_view
255        })
256    }
257
258    unsafe fn destroy_texture_view(&self, view: Box<dyn DynTextureView>) {
259        unsafe { D::destroy_texture_view(self, view.unbox()) };
260    }
261
262    unsafe fn create_sampler(
263        &self,
264        desc: &SamplerDescriptor,
265    ) -> Result<Box<dyn DynSampler>, DeviceError> {
266        unsafe { D::create_sampler(self, desc) }.map(|b| {
267            let boxed_sampler: Box<<D::A as Api>::Sampler> = Box::new(b);
268            let boxed_sampler: Box<dyn DynSampler> = boxed_sampler;
269            boxed_sampler
270        })
271    }
272
273    unsafe fn destroy_sampler(&self, sampler: Box<dyn DynSampler>) {
274        unsafe { D::destroy_sampler(self, sampler.unbox()) };
275    }
276
277    unsafe fn create_command_encoder(
278        &self,
279        desc: &CommandEncoderDescriptor<'_, dyn DynQueue>,
280    ) -> Result<Box<dyn DynCommandEncoder>, DeviceError> {
281        let desc = CommandEncoderDescriptor {
282            label: desc.label,
283            queue: desc.queue.expect_downcast_ref(),
284        };
285        unsafe { D::create_command_encoder(self, &desc) }
286            .map(|b| -> Box<dyn DynCommandEncoder> { Box::new(b) })
287    }
288
289    unsafe fn create_bind_group_layout(
290        &self,
291        desc: &BindGroupLayoutDescriptor,
292    ) -> Result<Box<dyn DynBindGroupLayout>, DeviceError> {
293        unsafe { D::create_bind_group_layout(self, desc) }
294            .map(|b| -> Box<dyn DynBindGroupLayout> { Box::new(b) })
295    }
296
297    unsafe fn destroy_bind_group_layout(&self, bg_layout: Box<dyn DynBindGroupLayout>) {
298        unsafe { D::destroy_bind_group_layout(self, bg_layout.unbox()) };
299    }
300
301    unsafe fn create_pipeline_layout(
302        &self,
303        desc: &PipelineLayoutDescriptor<dyn DynBindGroupLayout>,
304    ) -> Result<Box<dyn DynPipelineLayout>, DeviceError> {
305        let bind_group_layouts: Vec<_> = desc
306            .bind_group_layouts
307            .iter()
308            .map(|bgl| bgl.map(|bgl| bgl.expect_downcast_ref()))
309            .collect();
310        let desc = PipelineLayoutDescriptor {
311            label: desc.label,
312            bind_group_layouts: &bind_group_layouts,
313            immediate_size: desc.immediate_size,
314            flags: desc.flags,
315        };
316
317        unsafe { D::create_pipeline_layout(self, &desc) }
318            .map(|b| -> Box<dyn DynPipelineLayout> { Box::new(b) })
319    }
320
321    unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box<dyn DynPipelineLayout>) {
322        unsafe { D::destroy_pipeline_layout(self, pipeline_layout.unbox()) };
323    }
324
325    unsafe fn create_bind_group(
326        &self,
327        desc: &BindGroupDescriptor<
328            dyn DynBindGroupLayout,
329            dyn DynBuffer,
330            dyn DynSampler,
331            dyn DynTextureView,
332            dyn DynAccelerationStructure,
333        >,
334    ) -> Result<Box<dyn DynBindGroup>, DeviceError> {
335        let buffers: Vec<_> = desc
336            .buffers
337            .iter()
338            .map(|b| b.clone().expect_downcast())
339            .collect();
340        let samplers: Vec<_> = desc
341            .samplers
342            .iter()
343            .map(|s| s.expect_downcast_ref())
344            .collect();
345        let textures: Vec<_> = desc
346            .textures
347            .iter()
348            .map(|t| t.clone().expect_downcast())
349            .collect();
350        let acceleration_structures: Vec<_> = desc
351            .acceleration_structures
352            .iter()
353            .map(|a| a.expect_downcast_ref())
354            .collect();
355        let external_textures: Vec<_> = desc
356            .external_textures
357            .iter()
358            .map(|et| et.clone().expect_downcast())
359            .collect();
360
361        let desc = BindGroupDescriptor {
362            label: desc.label.to_owned(),
363            layout: desc.layout.expect_downcast_ref(),
364            buffers: &buffers,
365            samplers: &samplers,
366            textures: &textures,
367            entries: desc.entries,
368            acceleration_structures: &acceleration_structures,
369            external_textures: &external_textures,
370        };
371
372        unsafe { D::create_bind_group(self, &desc) }
373            .map(|b| -> Box<dyn DynBindGroup> { Box::new(b) })
374    }
375
376    unsafe fn destroy_bind_group(&self, group: Box<dyn DynBindGroup>) {
377        unsafe { D::destroy_bind_group(self, group.unbox()) };
378    }
379
380    unsafe fn create_shader_module(
381        &self,
382        desc: &ShaderModuleDescriptor,
383        shader: ShaderInput,
384    ) -> Result<Box<dyn DynShaderModule>, ShaderError> {
385        unsafe { D::create_shader_module(self, desc, shader) }
386            .map(|b| -> Box<dyn DynShaderModule> { Box::new(b) })
387    }
388
389    unsafe fn destroy_shader_module(&self, module: Box<dyn DynShaderModule>) {
390        unsafe { D::destroy_shader_module(self, module.unbox()) };
391    }
392
393    unsafe fn create_render_pipeline(
394        &self,
395        desc: &RenderPipelineDescriptor<
396            dyn DynPipelineLayout,
397            dyn DynShaderModule,
398            dyn DynPipelineCache,
399        >,
400    ) -> Result<Box<dyn DynRenderPipeline>, PipelineError> {
401        let desc = RenderPipelineDescriptor {
402            label: desc.label,
403            layout: desc.layout.expect_downcast_ref(),
404            vertex_processor: match &desc.vertex_processor {
405                crate::VertexProcessor::Standard {
406                    vertex_buffers,
407                    vertex_stage,
408                } => crate::VertexProcessor::Standard {
409                    vertex_buffers,
410                    vertex_stage: vertex_stage.clone().expect_downcast(),
411                },
412                crate::VertexProcessor::Mesh {
413                    task_stage: task,
414                    mesh_stage: mesh,
415                } => crate::VertexProcessor::Mesh {
416                    task_stage: task.as_ref().map(|a| a.clone().expect_downcast()),
417                    mesh_stage: mesh.clone().expect_downcast(),
418                },
419            },
420            primitive: desc.primitive,
421            depth_stencil: desc.depth_stencil.clone(),
422            multisample: desc.multisample,
423            fragment_stage: desc.fragment_stage.clone().map(|f| f.expect_downcast()),
424            color_targets: desc.color_targets,
425            multiview_mask: desc.multiview_mask,
426            cache: desc.cache.map(|c| c.expect_downcast_ref()),
427        };
428
429        unsafe { D::create_render_pipeline(self, &desc) }
430            .map(|b| -> Box<dyn DynRenderPipeline> { Box::new(b) })
431    }
432
433    unsafe fn destroy_render_pipeline(&self, pipeline: Box<dyn DynRenderPipeline>) {
434        unsafe { D::destroy_render_pipeline(self, pipeline.unbox()) };
435    }
436
437    unsafe fn create_compute_pipeline(
438        &self,
439        desc: &ComputePipelineDescriptor<
440            dyn DynPipelineLayout,
441            dyn DynShaderModule,
442            dyn DynPipelineCache,
443        >,
444    ) -> Result<Box<dyn DynComputePipeline>, PipelineError> {
445        let desc = ComputePipelineDescriptor {
446            label: desc.label,
447            layout: desc.layout.expect_downcast_ref(),
448            stage: desc.stage.clone().expect_downcast(),
449            cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()),
450        };
451
452        unsafe { D::create_compute_pipeline(self, &desc) }
453            .map(|b| -> Box<dyn DynComputePipeline> { Box::new(b) })
454    }
455
456    unsafe fn destroy_compute_pipeline(&self, pipeline: Box<dyn DynComputePipeline>) {
457        unsafe { D::destroy_compute_pipeline(self, pipeline.unbox()) };
458    }
459
460    unsafe fn create_ray_tracing_pipeline(
461        &self,
462        desc: &RayTracingPipelineDescriptor<
463            dyn DynPipelineLayout,
464            dyn DynShaderModule,
465            dyn DynPipelineCache,
466        >,
467    ) -> Result<Box<dyn DynRayTracingPipeline>, PipelineError> {
468        let ray_intersection: Vec<_> = desc
469            .intersection
470            .iter()
471            .map(|stage| RayObjectIntersectionState {
472                closest_hit: stage.closest_hit.clone().expect_downcast(),
473                any_hit: stage
474                    .any_hit
475                    .as_ref()
476                    .map(|stage| stage.clone().expect_downcast()),
477            })
478            .collect();
479
480        let desc = RayTracingPipelineDescriptor {
481            label: desc.label,
482            layout: desc.layout.expect_downcast_ref(),
483            ray_generation: desc.ray_generation.clone().expect_downcast(),
484            miss: desc.miss.clone().expect_downcast(),
485            intersection: &ray_intersection,
486            max_recursion_depth: desc.max_recursion_depth,
487            cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()),
488        };
489
490        unsafe { D::create_ray_tracing_pipeline(self, &desc) }
491            .map(|b| -> Box<dyn DynRayTracingPipeline> { Box::new(b) })
492    }
493
494    unsafe fn destroy_ray_tracing_pipeline(&self, pipeline: Box<dyn DynRayTracingPipeline>) {
495        unsafe {
496            D::destroy_ray_tracing_pipeline(self, pipeline.unbox());
497        };
498    }
499    unsafe fn get_raytracing_pipeline_group_data(
500        &self,
501        pipeline: &dyn DynRayTracingPipeline,
502        groups: core::ops::Range<u32>,
503    ) -> Result<Vec<u8>, DeviceError> {
504        unsafe {
505            D::get_raytracing_pipeline_group_data(self, pipeline.expect_downcast_ref(), groups)
506        }
507    }
508
509    unsafe fn create_pipeline_cache(
510        &self,
511        desc: &PipelineCacheDescriptor<'_>,
512    ) -> Result<Box<dyn DynPipelineCache>, PipelineCacheError> {
513        unsafe { D::create_pipeline_cache(self, desc) }
514            .map(|b| -> Box<dyn DynPipelineCache> { Box::new(b) })
515    }
516
517    fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> {
518        D::pipeline_cache_validation_key(self)
519    }
520
521    unsafe fn destroy_pipeline_cache(&self, pipeline_cache: Box<dyn DynPipelineCache>) {
522        unsafe { D::destroy_pipeline_cache(self, pipeline_cache.unbox()) };
523    }
524
525    unsafe fn create_query_set(
526        &self,
527        desc: &wgt::QuerySetDescriptor<Label>,
528    ) -> Result<Box<dyn DynQuerySet>, DeviceError> {
529        unsafe { D::create_query_set(self, desc) }.map(|b| -> Box<dyn DynQuerySet> { Box::new(b) })
530    }
531
532    unsafe fn destroy_query_set(&self, query_set: Box<dyn DynQuerySet>) {
533        unsafe { D::destroy_query_set(self, query_set.unbox()) };
534    }
535
536    unsafe fn create_fence(&self) -> Result<Box<dyn DynFence>, DeviceError> {
537        unsafe { D::create_fence(self) }.map(|b| -> Box<dyn DynFence> { Box::new(b) })
538    }
539
540    unsafe fn destroy_fence(&self, fence: Box<dyn DynFence>) {
541        unsafe { D::destroy_fence(self, fence.unbox()) };
542    }
543
544    unsafe fn get_fence_value(&self, fence: &dyn DynFence) -> Result<FenceValue, DeviceError> {
545        let fence = fence.expect_downcast_ref();
546        unsafe { D::get_fence_value(self, fence) }
547    }
548
549    unsafe fn wait(
550        &self,
551        fence: &dyn DynFence,
552        value: FenceValue,
553        timeout: Option<core::time::Duration>,
554    ) -> Result<bool, DeviceError> {
555        let fence = fence.expect_downcast_ref();
556        unsafe { D::wait(self, fence, value, timeout) }
557    }
558
559    unsafe fn start_graphics_debugger_capture(&self) -> bool {
560        unsafe { D::start_graphics_debugger_capture(self) }
561    }
562
563    unsafe fn stop_graphics_debugger_capture(&self) {
564        unsafe { D::stop_graphics_debugger_capture(self) }
565    }
566
567    unsafe fn pipeline_cache_get_data(&self, cache: &dyn DynPipelineCache) -> Option<Vec<u8>> {
568        let cache = cache.expect_downcast_ref();
569        unsafe { D::pipeline_cache_get_data(self, cache) }
570    }
571
572    unsafe fn create_acceleration_structure(
573        &self,
574        desc: &AccelerationStructureDescriptor,
575    ) -> Result<Box<dyn DynAccelerationStructure>, DeviceError> {
576        unsafe { D::create_acceleration_structure(self, desc) }
577            .map(|b| -> Box<dyn DynAccelerationStructure> { Box::new(b) })
578    }
579
580    unsafe fn get_acceleration_structure_build_sizes(
581        &self,
582        desc: &GetAccelerationStructureBuildSizesDescriptor<dyn DynBuffer>,
583    ) -> AccelerationStructureBuildSizes {
584        let entries = desc.entries.expect_downcast();
585        let desc = GetAccelerationStructureBuildSizesDescriptor {
586            entries: &entries,
587            flags: desc.flags,
588        };
589        unsafe { D::get_acceleration_structure_build_sizes(self, &desc) }
590    }
591
592    unsafe fn get_acceleration_structure_device_address(
593        &self,
594        acceleration_structure: &dyn DynAccelerationStructure,
595    ) -> wgt::BufferAddress {
596        let acceleration_structure = acceleration_structure.expect_downcast_ref();
597        unsafe { D::get_acceleration_structure_device_address(self, acceleration_structure) }
598    }
599
600    unsafe fn destroy_acceleration_structure(
601        &self,
602        acceleration_structure: Box<dyn DynAccelerationStructure>,
603    ) {
604        unsafe { D::destroy_acceleration_structure(self, acceleration_structure.unbox()) }
605    }
606
607    fn tlas_instance_to_bytes(&self, instance: TlasInstance) -> Vec<u8> {
608        D::tlas_instance_to_bytes(self, instance)
609    }
610
611    fn get_internal_counters(&self) -> wgt::HalCounters {
612        D::get_internal_counters(self)
613    }
614
615    fn generate_allocator_report(&self) -> Option<wgt::AllocatorReport> {
616        D::generate_allocator_report(self)
617    }
618
619    fn check_if_oom(&self) -> Result<(), DeviceError> {
620        D::check_if_oom(self)
621    }
622}