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>, wgt::BufferAddress), 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, to_extend: &mut 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>, wgt::BufferAddress), DeviceError> {
190        unsafe { D::create_buffer(self, desc) }
191            .map(|(b, size)| -> (Box<dyn DynBuffer>, _) { (Box::new(b), size) })
192    }
193
194    unsafe fn destroy_buffer(&self, buffer: Box<dyn DynBuffer>) {
195        unsafe { D::destroy_buffer(self, buffer.unbox()) };
196    }
197    unsafe fn add_raw_buffer(&self, buffer: &dyn DynBuffer) {
198        let buffer = buffer.expect_downcast_ref();
199        unsafe { D::add_raw_buffer(self, buffer) };
200    }
201
202    unsafe fn map_buffer(
203        &self,
204        buffer: &dyn DynBuffer,
205        range: MemoryRange,
206    ) -> Result<BufferMapping, DeviceError> {
207        let buffer = buffer.expect_downcast_ref();
208        unsafe { D::map_buffer(self, buffer, range) }
209    }
210
211    unsafe fn unmap_buffer(&self, buffer: &dyn DynBuffer) {
212        let buffer = buffer.expect_downcast_ref();
213        unsafe { D::unmap_buffer(self, buffer) }
214    }
215
216    unsafe fn flush_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
217        let buffer = buffer.expect_downcast_ref();
218        unsafe { D::flush_mapped_ranges(self, buffer, ranges.iter().cloned()) }
219    }
220
221    unsafe fn invalidate_mapped_ranges(&self, buffer: &dyn DynBuffer, ranges: &[MemoryRange]) {
222        let buffer = buffer.expect_downcast_ref();
223        unsafe { D::invalidate_mapped_ranges(self, buffer, ranges.iter().cloned()) }
224    }
225
226    unsafe fn create_texture(
227        &self,
228        desc: &TextureDescriptor,
229    ) -> Result<Box<dyn DynTexture>, DeviceError> {
230        unsafe { D::create_texture(self, desc) }.map(|b| {
231            let boxed_texture: Box<<D::A as Api>::Texture> = Box::new(b);
232            let boxed_texture: Box<dyn DynTexture> = boxed_texture;
233            boxed_texture
234        })
235    }
236
237    unsafe fn destroy_texture(&self, texture: Box<dyn DynTexture>) {
238        unsafe { D::destroy_texture(self, texture.unbox()) };
239    }
240
241    unsafe fn add_raw_texture(&self, texture: &dyn DynTexture) {
242        let texture = texture.expect_downcast_ref();
243        unsafe { D::add_raw_texture(self, texture) };
244    }
245
246    unsafe fn create_texture_view(
247        &self,
248        texture: &dyn DynTexture,
249        desc: &TextureViewDescriptor,
250    ) -> Result<Box<dyn DynTextureView>, DeviceError> {
251        let texture = texture.expect_downcast_ref();
252        unsafe { D::create_texture_view(self, texture, desc) }.map(|b| {
253            let boxed_texture_view: Box<<D::A as Api>::TextureView> = Box::new(b);
254            let boxed_texture_view: Box<dyn DynTextureView> = boxed_texture_view;
255            boxed_texture_view
256        })
257    }
258
259    unsafe fn destroy_texture_view(&self, view: Box<dyn DynTextureView>) {
260        unsafe { D::destroy_texture_view(self, view.unbox()) };
261    }
262
263    unsafe fn create_sampler(
264        &self,
265        desc: &SamplerDescriptor,
266    ) -> Result<Box<dyn DynSampler>, DeviceError> {
267        unsafe { D::create_sampler(self, desc) }.map(|b| {
268            let boxed_sampler: Box<<D::A as Api>::Sampler> = Box::new(b);
269            let boxed_sampler: Box<dyn DynSampler> = boxed_sampler;
270            boxed_sampler
271        })
272    }
273
274    unsafe fn destroy_sampler(&self, sampler: Box<dyn DynSampler>) {
275        unsafe { D::destroy_sampler(self, sampler.unbox()) };
276    }
277
278    unsafe fn create_command_encoder(
279        &self,
280        desc: &CommandEncoderDescriptor<'_, dyn DynQueue>,
281    ) -> Result<Box<dyn DynCommandEncoder>, DeviceError> {
282        let desc = CommandEncoderDescriptor {
283            label: desc.label,
284            queue: desc.queue.expect_downcast_ref(),
285        };
286        unsafe { D::create_command_encoder(self, &desc) }
287            .map(|b| -> Box<dyn DynCommandEncoder> { Box::new(b) })
288    }
289
290    unsafe fn create_bind_group_layout(
291        &self,
292        desc: &BindGroupLayoutDescriptor,
293    ) -> Result<Box<dyn DynBindGroupLayout>, DeviceError> {
294        unsafe { D::create_bind_group_layout(self, desc) }
295            .map(|b| -> Box<dyn DynBindGroupLayout> { Box::new(b) })
296    }
297
298    unsafe fn destroy_bind_group_layout(&self, bg_layout: Box<dyn DynBindGroupLayout>) {
299        unsafe { D::destroy_bind_group_layout(self, bg_layout.unbox()) };
300    }
301
302    unsafe fn create_pipeline_layout(
303        &self,
304        desc: &PipelineLayoutDescriptor<dyn DynBindGroupLayout>,
305    ) -> Result<Box<dyn DynPipelineLayout>, DeviceError> {
306        let bind_group_layouts: Vec<_> = desc
307            .bind_group_layouts
308            .iter()
309            .map(|bgl| bgl.map(|bgl| bgl.expect_downcast_ref()))
310            .collect();
311        let desc = PipelineLayoutDescriptor {
312            label: desc.label,
313            bind_group_layouts: &bind_group_layouts,
314            immediate_size: desc.immediate_size,
315            flags: desc.flags,
316        };
317
318        unsafe { D::create_pipeline_layout(self, &desc) }
319            .map(|b| -> Box<dyn DynPipelineLayout> { Box::new(b) })
320    }
321
322    unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Box<dyn DynPipelineLayout>) {
323        unsafe { D::destroy_pipeline_layout(self, pipeline_layout.unbox()) };
324    }
325
326    unsafe fn create_bind_group(
327        &self,
328        desc: &BindGroupDescriptor<
329            dyn DynBindGroupLayout,
330            dyn DynBuffer,
331            dyn DynSampler,
332            dyn DynTextureView,
333            dyn DynAccelerationStructure,
334        >,
335    ) -> Result<Box<dyn DynBindGroup>, DeviceError> {
336        let buffers: Vec<_> = desc
337            .buffers
338            .iter()
339            .map(|b| b.clone().expect_downcast())
340            .collect();
341        let samplers: Vec<_> = desc
342            .samplers
343            .iter()
344            .map(|s| s.expect_downcast_ref())
345            .collect();
346        let textures: Vec<_> = desc
347            .textures
348            .iter()
349            .map(|t| t.clone().expect_downcast())
350            .collect();
351        let acceleration_structures: Vec<_> = desc
352            .acceleration_structures
353            .iter()
354            .map(|a| a.expect_downcast_ref())
355            .collect();
356        let external_textures: Vec<_> = desc
357            .external_textures
358            .iter()
359            .map(|et| et.clone().expect_downcast())
360            .collect();
361
362        let desc = BindGroupDescriptor {
363            label: desc.label.to_owned(),
364            layout: desc.layout.expect_downcast_ref(),
365            buffers: &buffers,
366            samplers: &samplers,
367            textures: &textures,
368            entries: desc.entries,
369            acceleration_structures: &acceleration_structures,
370            external_textures: &external_textures,
371        };
372
373        unsafe { D::create_bind_group(self, &desc) }
374            .map(|b| -> Box<dyn DynBindGroup> { Box::new(b) })
375    }
376
377    unsafe fn destroy_bind_group(&self, group: Box<dyn DynBindGroup>) {
378        unsafe { D::destroy_bind_group(self, group.unbox()) };
379    }
380
381    unsafe fn create_shader_module(
382        &self,
383        desc: &ShaderModuleDescriptor,
384        shader: ShaderInput,
385    ) -> Result<Box<dyn DynShaderModule>, ShaderError> {
386        unsafe { D::create_shader_module(self, desc, shader) }
387            .map(|b| -> Box<dyn DynShaderModule> { Box::new(b) })
388    }
389
390    unsafe fn destroy_shader_module(&self, module: Box<dyn DynShaderModule>) {
391        unsafe { D::destroy_shader_module(self, module.unbox()) };
392    }
393
394    unsafe fn create_render_pipeline(
395        &self,
396        desc: &RenderPipelineDescriptor<
397            dyn DynPipelineLayout,
398            dyn DynShaderModule,
399            dyn DynPipelineCache,
400        >,
401    ) -> Result<Box<dyn DynRenderPipeline>, PipelineError> {
402        let desc = RenderPipelineDescriptor {
403            label: desc.label,
404            layout: desc.layout.expect_downcast_ref(),
405            vertex_processor: match &desc.vertex_processor {
406                crate::VertexProcessor::Standard {
407                    vertex_buffers,
408                    vertex_stage,
409                } => crate::VertexProcessor::Standard {
410                    vertex_buffers,
411                    vertex_stage: vertex_stage.clone().expect_downcast(),
412                },
413                crate::VertexProcessor::Mesh {
414                    task_stage: task,
415                    mesh_stage: mesh,
416                } => crate::VertexProcessor::Mesh {
417                    task_stage: task.as_ref().map(|a| a.clone().expect_downcast()),
418                    mesh_stage: mesh.clone().expect_downcast(),
419                },
420            },
421            primitive: desc.primitive,
422            depth_stencil: desc.depth_stencil.clone(),
423            multisample: desc.multisample,
424            fragment_stage: desc.fragment_stage.clone().map(|f| f.expect_downcast()),
425            color_targets: desc.color_targets,
426            multiview_mask: desc.multiview_mask,
427            cache: desc.cache.map(|c| c.expect_downcast_ref()),
428        };
429
430        unsafe { D::create_render_pipeline(self, &desc) }
431            .map(|b| -> Box<dyn DynRenderPipeline> { Box::new(b) })
432    }
433
434    unsafe fn destroy_render_pipeline(&self, pipeline: Box<dyn DynRenderPipeline>) {
435        unsafe { D::destroy_render_pipeline(self, pipeline.unbox()) };
436    }
437
438    unsafe fn create_compute_pipeline(
439        &self,
440        desc: &ComputePipelineDescriptor<
441            dyn DynPipelineLayout,
442            dyn DynShaderModule,
443            dyn DynPipelineCache,
444        >,
445    ) -> Result<Box<dyn DynComputePipeline>, PipelineError> {
446        let desc = ComputePipelineDescriptor {
447            label: desc.label,
448            layout: desc.layout.expect_downcast_ref(),
449            stage: desc.stage.clone().expect_downcast(),
450            cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()),
451        };
452
453        unsafe { D::create_compute_pipeline(self, &desc) }
454            .map(|b| -> Box<dyn DynComputePipeline> { Box::new(b) })
455    }
456
457    unsafe fn destroy_compute_pipeline(&self, pipeline: Box<dyn DynComputePipeline>) {
458        unsafe { D::destroy_compute_pipeline(self, pipeline.unbox()) };
459    }
460
461    unsafe fn create_ray_tracing_pipeline(
462        &self,
463        desc: &RayTracingPipelineDescriptor<
464            dyn DynPipelineLayout,
465            dyn DynShaderModule,
466            dyn DynPipelineCache,
467        >,
468    ) -> Result<Box<dyn DynRayTracingPipeline>, PipelineError> {
469        let ray_intersection: Vec<_> = desc
470            .intersection
471            .iter()
472            .map(|stage| RayObjectIntersectionState {
473                closest_hit: stage.closest_hit.clone().expect_downcast(),
474                any_hit: stage
475                    .any_hit
476                    .as_ref()
477                    .map(|stage| stage.clone().expect_downcast()),
478            })
479            .collect();
480
481        let desc = RayTracingPipelineDescriptor {
482            label: desc.label,
483            layout: desc.layout.expect_downcast_ref(),
484            ray_generation: desc.ray_generation.clone().expect_downcast(),
485            miss: desc.miss.clone().expect_downcast(),
486            intersection: &ray_intersection,
487            max_recursion_depth: desc.max_recursion_depth,
488            cache: desc.cache.as_ref().map(|c| c.expect_downcast_ref()),
489        };
490
491        unsafe { D::create_ray_tracing_pipeline(self, &desc) }
492            .map(|b| -> Box<dyn DynRayTracingPipeline> { Box::new(b) })
493    }
494
495    unsafe fn destroy_ray_tracing_pipeline(&self, pipeline: Box<dyn DynRayTracingPipeline>) {
496        unsafe {
497            D::destroy_ray_tracing_pipeline(self, pipeline.unbox());
498        };
499    }
500    unsafe fn get_raytracing_pipeline_group_data(
501        &self,
502        pipeline: &dyn DynRayTracingPipeline,
503        groups: core::ops::Range<u32>,
504    ) -> Result<Vec<u8>, DeviceError> {
505        unsafe {
506            D::get_raytracing_pipeline_group_data(self, pipeline.expect_downcast_ref(), groups)
507        }
508    }
509
510    unsafe fn create_pipeline_cache(
511        &self,
512        desc: &PipelineCacheDescriptor<'_>,
513    ) -> Result<Box<dyn DynPipelineCache>, PipelineCacheError> {
514        unsafe { D::create_pipeline_cache(self, desc) }
515            .map(|b| -> Box<dyn DynPipelineCache> { Box::new(b) })
516    }
517
518    fn pipeline_cache_validation_key(&self) -> Option<[u8; 16]> {
519        D::pipeline_cache_validation_key(self)
520    }
521
522    unsafe fn destroy_pipeline_cache(&self, pipeline_cache: Box<dyn DynPipelineCache>) {
523        unsafe { D::destroy_pipeline_cache(self, pipeline_cache.unbox()) };
524    }
525
526    unsafe fn create_query_set(
527        &self,
528        desc: &wgt::QuerySetDescriptor<Label>,
529    ) -> Result<Box<dyn DynQuerySet>, DeviceError> {
530        unsafe { D::create_query_set(self, desc) }.map(|b| -> Box<dyn DynQuerySet> { Box::new(b) })
531    }
532
533    unsafe fn destroy_query_set(&self, query_set: Box<dyn DynQuerySet>) {
534        unsafe { D::destroy_query_set(self, query_set.unbox()) };
535    }
536
537    unsafe fn create_fence(&self) -> Result<Box<dyn DynFence>, DeviceError> {
538        unsafe { D::create_fence(self) }.map(|b| -> Box<dyn DynFence> { Box::new(b) })
539    }
540
541    unsafe fn destroy_fence(&self, fence: Box<dyn DynFence>) {
542        unsafe { D::destroy_fence(self, fence.unbox()) };
543    }
544
545    unsafe fn get_fence_value(&self, fence: &dyn DynFence) -> Result<FenceValue, DeviceError> {
546        let fence = fence.expect_downcast_ref();
547        unsafe { D::get_fence_value(self, fence) }
548    }
549
550    unsafe fn wait(
551        &self,
552        fence: &dyn DynFence,
553        value: FenceValue,
554        timeout: Option<core::time::Duration>,
555    ) -> Result<bool, DeviceError> {
556        let fence = fence.expect_downcast_ref();
557        unsafe { D::wait(self, fence, value, timeout) }
558    }
559
560    unsafe fn start_graphics_debugger_capture(&self) -> bool {
561        unsafe { D::start_graphics_debugger_capture(self) }
562    }
563
564    unsafe fn stop_graphics_debugger_capture(&self) {
565        unsafe { D::stop_graphics_debugger_capture(self) }
566    }
567
568    unsafe fn pipeline_cache_get_data(&self, cache: &dyn DynPipelineCache) -> Option<Vec<u8>> {
569        let cache = cache.expect_downcast_ref();
570        unsafe { D::pipeline_cache_get_data(self, cache) }
571    }
572
573    unsafe fn create_acceleration_structure(
574        &self,
575        desc: &AccelerationStructureDescriptor,
576    ) -> Result<Box<dyn DynAccelerationStructure>, DeviceError> {
577        unsafe { D::create_acceleration_structure(self, desc) }
578            .map(|b| -> Box<dyn DynAccelerationStructure> { Box::new(b) })
579    }
580
581    unsafe fn get_acceleration_structure_build_sizes(
582        &self,
583        desc: &GetAccelerationStructureBuildSizesDescriptor<dyn DynBuffer>,
584    ) -> AccelerationStructureBuildSizes {
585        let entries = desc.entries.expect_downcast();
586        let desc = GetAccelerationStructureBuildSizesDescriptor {
587            entries: &entries,
588            flags: desc.flags,
589        };
590        unsafe { D::get_acceleration_structure_build_sizes(self, &desc) }
591    }
592
593    unsafe fn get_acceleration_structure_device_address(
594        &self,
595        acceleration_structure: &dyn DynAccelerationStructure,
596    ) -> wgt::BufferAddress {
597        let acceleration_structure = acceleration_structure.expect_downcast_ref();
598        unsafe { D::get_acceleration_structure_device_address(self, acceleration_structure) }
599    }
600
601    unsafe fn destroy_acceleration_structure(
602        &self,
603        acceleration_structure: Box<dyn DynAccelerationStructure>,
604    ) {
605        unsafe { D::destroy_acceleration_structure(self, acceleration_structure.unbox()) }
606    }
607
608    fn tlas_instance_to_bytes(&self, instance: TlasInstance, to_extend: &mut Vec<u8>) {
609        D::tlas_instance_to_bytes(self, instance, to_extend)
610    }
611
612    fn get_internal_counters(&self) -> wgt::HalCounters {
613        D::get_internal_counters(self)
614    }
615
616    fn generate_allocator_report(&self) -> Option<wgt::AllocatorReport> {
617        D::generate_allocator_report(self)
618    }
619
620    fn check_if_oom(&self) -> Result<(), DeviceError> {
621        D::check_if_oom(self)
622    }
623}