Skip to main content

wgpu_hal/dynamic/
command.rs

1use alloc::{boxed::Box, vec::Vec};
2use core::ops::Range;
3
4use crate::{
5    AccelerationStructureBarrier, Api, Attachment, BufferBarrier, BufferBinding, BufferCopy,
6    BufferTextureCopy, BuildAccelerationStructureDescriptor, ColorAttachment, CommandEncoder,
7    ComputePassDescriptor, DepthStencilAttachment, DeviceError, DynRayTracingPipeline, Label,
8    MemoryRange, PassTimestampWrites, RayTracingPassDescriptor, Rect, RenderPassDescriptor,
9    TextureBarrier, TextureCopy,
10};
11
12use super::{
13    DynAccelerationStructure, DynBindGroup, DynBuffer, DynCommandBuffer, DynComputePipeline,
14    DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynResourceExt as _,
15    DynTexture, DynTextureView,
16};
17
18pub trait DynCommandEncoder: DynResource + core::fmt::Debug {
19    unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>;
20
21    unsafe fn discard_encoding(&mut self);
22
23    unsafe fn end_encoding(&mut self) -> Result<Box<dyn DynCommandBuffer>, DeviceError>;
24
25    unsafe fn reset_all(&mut self, command_buffers: Vec<Box<dyn DynCommandBuffer>>);
26
27    unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]);
28    unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]);
29
30    unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange);
31
32    unsafe fn copy_buffer_to_buffer(
33        &mut self,
34        src: &dyn DynBuffer,
35        dst: &dyn DynBuffer,
36        regions: &[BufferCopy],
37    );
38
39    unsafe fn copy_texture_to_texture(
40        &mut self,
41        src: &dyn DynTexture,
42        src_usage: wgt::TextureUses,
43        dst: &dyn DynTexture,
44        regions: &[TextureCopy],
45    );
46
47    unsafe fn copy_buffer_to_texture(
48        &mut self,
49        src: &dyn DynBuffer,
50        dst: &dyn DynTexture,
51        regions: &[BufferTextureCopy],
52    );
53
54    unsafe fn copy_texture_to_buffer(
55        &mut self,
56        src: &dyn DynTexture,
57        src_usage: wgt::TextureUses,
58        dst: &dyn DynBuffer,
59        regions: &[BufferTextureCopy],
60    );
61
62    unsafe fn set_bind_group(
63        &mut self,
64        layout: &dyn DynPipelineLayout,
65        index: u32,
66        group: &dyn DynBindGroup,
67        dynamic_offsets: &[wgt::DynamicOffset],
68    );
69
70    unsafe fn set_immediates(
71        &mut self,
72        layout: &dyn DynPipelineLayout,
73        offset_bytes: u32,
74        data: &[u32],
75    );
76
77    unsafe fn insert_debug_marker(&mut self, label: &str);
78    unsafe fn begin_debug_marker(&mut self, group_label: &str);
79    unsafe fn end_debug_marker(&mut self);
80
81    unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32);
82    unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32);
83    unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32);
84    unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range<u32>);
85    unsafe fn copy_query_results(
86        &mut self,
87        set: &dyn DynQuerySet,
88        range: Range<u32>,
89        buffer: &dyn DynBuffer,
90        offset: wgt::BufferAddress,
91        stride: wgt::BufferSize,
92    );
93
94    unsafe fn begin_render_pass(
95        &mut self,
96        desc: &RenderPassDescriptor<dyn DynQuerySet, dyn DynTextureView>,
97    ) -> Result<(), DeviceError>;
98    unsafe fn end_render_pass(&mut self);
99
100    unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline);
101
102    unsafe fn set_index_buffer<'a>(
103        &mut self,
104        binding: BufferBinding<'a, dyn DynBuffer>,
105        format: wgt::IndexFormat,
106    );
107
108    unsafe fn set_vertex_buffer<'a>(
109        &mut self,
110        index: u32,
111        binding: BufferBinding<'a, dyn DynBuffer>,
112    );
113    unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>);
114    unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>);
115    unsafe fn set_stencil_reference(&mut self, value: u32);
116    unsafe fn set_blend_constants(&mut self, color: &[f32; 4]);
117
118    unsafe fn draw(
119        &mut self,
120        first_vertex: u32,
121        vertex_count: u32,
122        first_instance: u32,
123        instance_count: u32,
124    );
125    unsafe fn draw_indexed(
126        &mut self,
127        first_index: u32,
128        index_count: u32,
129        base_vertex: i32,
130        first_instance: u32,
131        instance_count: u32,
132    );
133    unsafe fn draw_mesh_tasks(
134        &mut self,
135        group_count_x: u32,
136        group_count_y: u32,
137        group_count_z: u32,
138    );
139    unsafe fn draw_indirect(
140        &mut self,
141        buffer: &dyn DynBuffer,
142        offset: wgt::BufferAddress,
143        draw_count: u32,
144    );
145    unsafe fn draw_indexed_indirect(
146        &mut self,
147        buffer: &dyn DynBuffer,
148        offset: wgt::BufferAddress,
149        draw_count: u32,
150    );
151    unsafe fn draw_mesh_tasks_indirect(
152        &mut self,
153        buffer: &dyn DynBuffer,
154        offset: wgt::BufferAddress,
155        draw_count: u32,
156    );
157    unsafe fn draw_indirect_count(
158        &mut self,
159        buffer: &dyn DynBuffer,
160        offset: wgt::BufferAddress,
161        count_buffer: &dyn DynBuffer,
162        count_offset: wgt::BufferAddress,
163        max_count: u32,
164    );
165    unsafe fn draw_indexed_indirect_count(
166        &mut self,
167        buffer: &dyn DynBuffer,
168        offset: wgt::BufferAddress,
169        count_buffer: &dyn DynBuffer,
170        count_offset: wgt::BufferAddress,
171        max_count: u32,
172    );
173    unsafe fn draw_mesh_tasks_indirect_count(
174        &mut self,
175        buffer: &dyn DynBuffer,
176        offset: wgt::BufferAddress,
177        count_buffer: &dyn DynBuffer,
178        count_offset: wgt::BufferAddress,
179        max_count: u32,
180    );
181
182    unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<dyn DynQuerySet>);
183    unsafe fn end_compute_pass(&mut self);
184
185    unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline);
186
187    unsafe fn dispatch_workgroups(&mut self, count: [u32; 3]);
188    unsafe fn dispatch_workgroups_indirect(
189        &mut self,
190        buffer: &dyn DynBuffer,
191        offset: wgt::BufferAddress,
192    );
193
194    unsafe fn begin_ray_tracing_pass(&mut self, desc: &RayTracingPassDescriptor);
195    unsafe fn end_ray_tracing_pass(&mut self);
196
197    unsafe fn trace_rays(
198        &mut self,
199        count: [u32; 3],
200        ray_generation_group_data: crate::PipelineGroupData<dyn DynBuffer>,
201        miss_group_data: crate::PipelineGroupData<dyn DynBuffer>,
202        intersection_group_data: crate::PipelineGroupData<dyn DynBuffer>,
203    );
204
205    unsafe fn set_ray_tracing_pipeline(&mut self, pipeline: &dyn DynRayTracingPipeline);
206
207    unsafe fn build_acceleration_structures<'a>(
208        &mut self,
209        descriptors: &'a [BuildAccelerationStructureDescriptor<
210            'a,
211            dyn DynBuffer,
212            dyn DynAccelerationStructure,
213        >],
214    );
215    unsafe fn place_acceleration_structure_barrier(
216        &mut self,
217        barrier: AccelerationStructureBarrier,
218    );
219    unsafe fn copy_acceleration_structure_to_acceleration_structure(
220        &mut self,
221        src: &dyn DynAccelerationStructure,
222        dst: &dyn DynAccelerationStructure,
223        copy: wgt::AccelerationStructureCopy,
224    );
225    unsafe fn read_acceleration_structure_compact_size(
226        &mut self,
227        acceleration_structure: &dyn DynAccelerationStructure,
228        buf: &dyn DynBuffer,
229    );
230    unsafe fn set_acceleration_structure_dependencies(
231        &self,
232        command_buffers: &[Box<dyn DynCommandBuffer>],
233        dependencies: &[&dyn DynAccelerationStructure],
234    );
235}
236
237impl<C: CommandEncoder + DynResource> DynCommandEncoder for C {
238    unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError> {
239        unsafe { C::begin_encoding(self, label) }
240    }
241
242    unsafe fn discard_encoding(&mut self) {
243        unsafe { C::discard_encoding(self) }
244    }
245
246    unsafe fn end_encoding(&mut self) -> Result<Box<dyn DynCommandBuffer>, DeviceError> {
247        unsafe { C::end_encoding(self) }.map(|cb| {
248            let boxed_command_buffer: Box<<C::A as Api>::CommandBuffer> = Box::new(cb);
249            let boxed_command_buffer: Box<dyn DynCommandBuffer> = boxed_command_buffer;
250            boxed_command_buffer
251        })
252    }
253
254    unsafe fn reset_all(&mut self, command_buffers: Vec<Box<dyn DynCommandBuffer>>) {
255        unsafe { C::reset_all(self, command_buffers.into_iter().map(|cb| cb.unbox())) }
256    }
257
258    unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]) {
259        let barriers = barriers.iter().map(|barrier| BufferBarrier {
260            buffer: barrier.buffer.expect_downcast_ref(),
261            usage: barrier.usage.clone(),
262        });
263        unsafe { self.transition_buffers(barriers) };
264    }
265
266    unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]) {
267        let barriers = barriers.iter().map(|barrier| TextureBarrier {
268            texture: barrier.texture.expect_downcast_ref(),
269            usage: barrier.usage.clone(),
270            range: barrier.range,
271        });
272        unsafe { self.transition_textures(barriers) };
273    }
274
275    unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange) {
276        let buffer = buffer.expect_downcast_ref();
277        unsafe { C::clear_buffer(self, buffer, range) };
278    }
279
280    unsafe fn copy_buffer_to_buffer(
281        &mut self,
282        src: &dyn DynBuffer,
283        dst: &dyn DynBuffer,
284        regions: &[BufferCopy],
285    ) {
286        let src = src.expect_downcast_ref();
287        let dst = dst.expect_downcast_ref();
288        unsafe {
289            C::copy_buffer_to_buffer(self, src, dst, regions.iter().copied());
290        }
291    }
292
293    unsafe fn copy_texture_to_texture(
294        &mut self,
295        src: &dyn DynTexture,
296        src_usage: wgt::TextureUses,
297        dst: &dyn DynTexture,
298        regions: &[TextureCopy],
299    ) {
300        let src = src.expect_downcast_ref();
301        let dst = dst.expect_downcast_ref();
302        unsafe {
303            C::copy_texture_to_texture(self, src, src_usage, dst, regions.iter().cloned());
304        }
305    }
306
307    unsafe fn copy_buffer_to_texture(
308        &mut self,
309        src: &dyn DynBuffer,
310        dst: &dyn DynTexture,
311        regions: &[BufferTextureCopy],
312    ) {
313        let src = src.expect_downcast_ref();
314        let dst = dst.expect_downcast_ref();
315        unsafe {
316            C::copy_buffer_to_texture(self, src, dst, regions.iter().cloned());
317        }
318    }
319
320    unsafe fn copy_texture_to_buffer(
321        &mut self,
322        src: &dyn DynTexture,
323        src_usage: wgt::TextureUses,
324        dst: &dyn DynBuffer,
325        regions: &[BufferTextureCopy],
326    ) {
327        let src = src.expect_downcast_ref();
328        let dst = dst.expect_downcast_ref();
329        unsafe {
330            C::copy_texture_to_buffer(self, src, src_usage, dst, regions.iter().cloned());
331        }
332    }
333
334    unsafe fn set_bind_group(
335        &mut self,
336        layout: &dyn DynPipelineLayout,
337        index: u32,
338        group: &dyn DynBindGroup,
339        dynamic_offsets: &[wgt::DynamicOffset],
340    ) {
341        let layout = layout.expect_downcast_ref();
342        let group = group.expect_downcast_ref();
343        unsafe { C::set_bind_group(self, layout, index, group, dynamic_offsets) };
344    }
345
346    unsafe fn set_immediates(
347        &mut self,
348        layout: &dyn DynPipelineLayout,
349        offset_bytes: u32,
350        data: &[u32],
351    ) {
352        let layout = layout.expect_downcast_ref();
353        unsafe { C::set_immediates(self, layout, offset_bytes, data) };
354    }
355
356    unsafe fn insert_debug_marker(&mut self, label: &str) {
357        unsafe {
358            C::insert_debug_marker(self, label);
359        }
360    }
361
362    unsafe fn begin_debug_marker(&mut self, group_label: &str) {
363        unsafe {
364            C::begin_debug_marker(self, group_label);
365        }
366    }
367
368    unsafe fn end_debug_marker(&mut self) {
369        unsafe {
370            C::end_debug_marker(self);
371        }
372    }
373
374    unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32) {
375        let set = set.expect_downcast_ref();
376        unsafe { C::begin_query(self, set, index) };
377    }
378
379    unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32) {
380        let set = set.expect_downcast_ref();
381        unsafe { C::end_query(self, set, index) };
382    }
383
384    unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32) {
385        let set = set.expect_downcast_ref();
386        unsafe { C::write_timestamp(self, set, index) };
387    }
388
389    unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range<u32>) {
390        let set = set.expect_downcast_ref();
391        unsafe { C::reset_queries(self, set, range) };
392    }
393
394    unsafe fn copy_query_results(
395        &mut self,
396        set: &dyn DynQuerySet,
397        range: Range<u32>,
398        buffer: &dyn DynBuffer,
399        offset: wgt::BufferAddress,
400        stride: wgt::BufferSize,
401    ) {
402        let set = set.expect_downcast_ref();
403        let buffer = buffer.expect_downcast_ref();
404        unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) };
405    }
406
407    unsafe fn begin_render_pass(
408        &mut self,
409        desc: &RenderPassDescriptor<dyn DynQuerySet, dyn DynTextureView>,
410    ) -> Result<(), DeviceError> {
411        let color_attachments = desc
412            .color_attachments
413            .iter()
414            .map(|attachment| {
415                attachment
416                    .as_ref()
417                    .map(|attachment| attachment.expect_downcast())
418            })
419            .collect::<Vec<_>>();
420
421        let desc: RenderPassDescriptor<<C::A as Api>::QuerySet, <C::A as Api>::TextureView> =
422            RenderPassDescriptor {
423                label: desc.label,
424                extent: desc.extent,
425                sample_count: desc.sample_count,
426                color_attachments: &color_attachments,
427                depth_stencil_attachment: desc
428                    .depth_stencil_attachment
429                    .as_ref()
430                    .map(|ds| ds.expect_downcast()),
431                multiview_mask: desc.multiview_mask,
432                timestamp_writes: desc
433                    .timestamp_writes
434                    .as_ref()
435                    .map(|writes| writes.expect_downcast()),
436                occlusion_query_set: desc
437                    .occlusion_query_set
438                    .map(|set| set.expect_downcast_ref()),
439            };
440        unsafe { C::begin_render_pass(self, &desc) }
441    }
442
443    unsafe fn end_render_pass(&mut self) {
444        unsafe {
445            C::end_render_pass(self);
446        }
447    }
448
449    unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>) {
450        unsafe {
451            C::set_viewport(self, rect, depth_range);
452        }
453    }
454
455    unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>) {
456        unsafe {
457            C::set_scissor_rect(self, rect);
458        }
459    }
460
461    unsafe fn set_stencil_reference(&mut self, value: u32) {
462        unsafe {
463            C::set_stencil_reference(self, value);
464        }
465    }
466
467    unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {
468        unsafe { C::set_blend_constants(self, color) };
469    }
470
471    unsafe fn draw(
472        &mut self,
473        first_vertex: u32,
474        vertex_count: u32,
475        first_instance: u32,
476        instance_count: u32,
477    ) {
478        unsafe {
479            C::draw(
480                self,
481                first_vertex,
482                vertex_count,
483                first_instance,
484                instance_count,
485            )
486        };
487    }
488
489    unsafe fn draw_indexed(
490        &mut self,
491        first_index: u32,
492        index_count: u32,
493        base_vertex: i32,
494        first_instance: u32,
495        instance_count: u32,
496    ) {
497        unsafe {
498            C::draw_indexed(
499                self,
500                first_index,
501                index_count,
502                base_vertex,
503                first_instance,
504                instance_count,
505            )
506        };
507    }
508
509    unsafe fn draw_mesh_tasks(
510        &mut self,
511        group_count_x: u32,
512        group_count_y: u32,
513        group_count_z: u32,
514    ) {
515        unsafe { C::draw_mesh_tasks(self, group_count_x, group_count_y, group_count_z) };
516    }
517
518    unsafe fn draw_indirect(
519        &mut self,
520        buffer: &dyn DynBuffer,
521        offset: wgt::BufferAddress,
522        draw_count: u32,
523    ) {
524        let buffer = buffer.expect_downcast_ref();
525        unsafe { C::draw_indirect(self, buffer, offset, draw_count) };
526    }
527
528    unsafe fn draw_indexed_indirect(
529        &mut self,
530        buffer: &dyn DynBuffer,
531        offset: wgt::BufferAddress,
532        draw_count: u32,
533    ) {
534        let buffer = buffer.expect_downcast_ref();
535        unsafe { C::draw_indexed_indirect(self, buffer, offset, draw_count) };
536    }
537
538    unsafe fn draw_mesh_tasks_indirect(
539        &mut self,
540        buffer: &dyn DynBuffer,
541        offset: wgt::BufferAddress,
542        draw_count: u32,
543    ) {
544        let buffer = buffer.expect_downcast_ref();
545        unsafe { C::draw_mesh_tasks_indirect(self, buffer, offset, draw_count) };
546    }
547
548    unsafe fn draw_indirect_count(
549        &mut self,
550        buffer: &dyn DynBuffer,
551        offset: wgt::BufferAddress,
552        count_buffer: &dyn DynBuffer,
553        count_offset: wgt::BufferAddress,
554        max_count: u32,
555    ) {
556        let buffer = buffer.expect_downcast_ref();
557        let count_buffer = count_buffer.expect_downcast_ref();
558        unsafe {
559            C::draw_indirect_count(self, buffer, offset, count_buffer, count_offset, max_count)
560        };
561    }
562
563    unsafe fn draw_indexed_indirect_count(
564        &mut self,
565        buffer: &dyn DynBuffer,
566        offset: wgt::BufferAddress,
567        count_buffer: &dyn DynBuffer,
568        count_offset: wgt::BufferAddress,
569        max_count: u32,
570    ) {
571        let buffer = buffer.expect_downcast_ref();
572        let count_buffer = count_buffer.expect_downcast_ref();
573        unsafe {
574            C::draw_indexed_indirect_count(
575                self,
576                buffer,
577                offset,
578                count_buffer,
579                count_offset,
580                max_count,
581            )
582        };
583    }
584
585    unsafe fn draw_mesh_tasks_indirect_count(
586        &mut self,
587        buffer: &dyn DynBuffer,
588        offset: wgt::BufferAddress,
589        count_buffer: &dyn DynBuffer,
590        count_offset: wgt::BufferAddress,
591        max_count: u32,
592    ) {
593        let buffer = buffer.expect_downcast_ref();
594        let count_buffer = count_buffer.expect_downcast_ref();
595        unsafe {
596            C::draw_mesh_tasks_indirect_count(
597                self,
598                buffer,
599                offset,
600                count_buffer,
601                count_offset,
602                max_count,
603            )
604        };
605    }
606
607    unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<dyn DynQuerySet>) {
608        let desc = ComputePassDescriptor {
609            label: desc.label,
610            timestamp_writes: desc
611                .timestamp_writes
612                .as_ref()
613                .map(|writes| writes.expect_downcast()),
614        };
615        unsafe { C::begin_compute_pass(self, &desc) };
616    }
617
618    unsafe fn end_compute_pass(&mut self) {
619        unsafe { C::end_compute_pass(self) };
620    }
621
622    unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline) {
623        let pipeline = pipeline.expect_downcast_ref();
624        unsafe { C::set_compute_pipeline(self, pipeline) };
625    }
626
627    unsafe fn dispatch_workgroups(&mut self, count: [u32; 3]) {
628        unsafe { C::dispatch_workgroups(self, count) };
629    }
630
631    unsafe fn dispatch_workgroups_indirect(
632        &mut self,
633        buffer: &dyn DynBuffer,
634        offset: wgt::BufferAddress,
635    ) {
636        let buffer = buffer.expect_downcast_ref();
637        unsafe { C::dispatch_workgroups_indirect(self, buffer, offset) };
638    }
639
640    unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline) {
641        let pipeline = pipeline.expect_downcast_ref();
642        unsafe { C::set_render_pipeline(self, pipeline) };
643    }
644
645    unsafe fn set_index_buffer<'a>(
646        &mut self,
647        binding: BufferBinding<'a, dyn DynBuffer>,
648        format: wgt::IndexFormat,
649    ) {
650        let binding = binding.expect_downcast();
651        unsafe { self.set_index_buffer(binding, format) };
652    }
653
654    unsafe fn set_vertex_buffer<'a>(
655        &mut self,
656        index: u32,
657        binding: BufferBinding<'a, dyn DynBuffer>,
658    ) {
659        let binding = binding.expect_downcast();
660        unsafe { self.set_vertex_buffer(index, binding) };
661    }
662
663    unsafe fn begin_ray_tracing_pass(&mut self, desc: &RayTracingPassDescriptor) {
664        let desc = RayTracingPassDescriptor { label: desc.label };
665        unsafe { C::begin_ray_tracing_pass(self, &desc) };
666    }
667
668    unsafe fn end_ray_tracing_pass(&mut self) {
669        unsafe { C::end_ray_tracing_pass(self) };
670    }
671
672    unsafe fn set_ray_tracing_pipeline(&mut self, pipeline: &dyn DynRayTracingPipeline) {
673        let pipeline = pipeline.expect_downcast_ref();
674        unsafe { C::set_ray_tracing_pipeline(self, pipeline) };
675    }
676
677    unsafe fn trace_rays<'a>(
678        &mut self,
679        count: [u32; 3],
680        ray_generation_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
681        miss_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
682        intersection_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
683    ) {
684        let downcast_group_data =
685            |data: crate::PipelineGroupData<'a, dyn DynBuffer>| crate::PipelineGroupData {
686                buffer: data.buffer.expect_downcast_ref(),
687                offset: data.offset,
688                stride: data.stride,
689                count: data.count,
690            };
691
692        unsafe {
693            C::trace_rays(
694                self,
695                count,
696                downcast_group_data(ray_generation_group_data),
697                downcast_group_data(miss_group_data),
698                downcast_group_data(intersection_group_data),
699            );
700        }
701    }
702
703    unsafe fn build_acceleration_structures<'a>(
704        &mut self,
705        descriptors: &'a [BuildAccelerationStructureDescriptor<
706            'a,
707            dyn DynBuffer,
708            dyn DynAccelerationStructure,
709        >],
710    ) {
711        // Need to collect entries here so we can reference them in the descriptor.
712        // TODO: API should be redesigned to avoid this and other descriptor copies that happen due to the dyn api.
713        let descriptor_entries = descriptors
714            .iter()
715            .map(|d| d.entries.expect_downcast())
716            .collect::<Vec<_>>();
717        let descriptors = descriptors
718            .iter()
719            .zip(descriptor_entries.iter())
720            .map(|(d, entries)| BuildAccelerationStructureDescriptor::<
721                <C::A as Api>::Buffer,
722                <C::A as Api>::AccelerationStructure,
723            > {
724                entries,
725                mode: d.mode,
726                flags: d.flags,
727                source_acceleration_structure: d
728                    .source_acceleration_structure
729                    .map(|a| a.expect_downcast_ref()),
730                destination_acceleration_structure: d
731                    .destination_acceleration_structure
732                    .expect_downcast_ref(),
733                scratch_buffer: d.scratch_buffer.expect_downcast_ref(),
734                scratch_buffer_offset: d.scratch_buffer_offset,
735            });
736        unsafe { C::build_acceleration_structures(self, descriptors.len() as _, descriptors) };
737    }
738
739    unsafe fn place_acceleration_structure_barrier(
740        &mut self,
741        barrier: AccelerationStructureBarrier,
742    ) {
743        unsafe { C::place_acceleration_structure_barrier(self, barrier) };
744    }
745
746    unsafe fn copy_acceleration_structure_to_acceleration_structure(
747        &mut self,
748        src: &dyn DynAccelerationStructure,
749        dst: &dyn DynAccelerationStructure,
750        copy: wgt::AccelerationStructureCopy,
751    ) {
752        let src = src.expect_downcast_ref();
753        let dst = dst.expect_downcast_ref();
754        unsafe { C::copy_acceleration_structure_to_acceleration_structure(self, src, dst, copy) };
755    }
756    unsafe fn read_acceleration_structure_compact_size(
757        &mut self,
758        acceleration_structure: &dyn DynAccelerationStructure,
759        buf: &dyn DynBuffer,
760    ) {
761        let acceleration_structure = acceleration_structure.expect_downcast_ref();
762        let buf = buf.expect_downcast_ref();
763        unsafe { C::read_acceleration_structure_compact_size(self, acceleration_structure, buf) }
764    }
765
766    unsafe fn set_acceleration_structure_dependencies(
767        &self,
768        command_buffers: &[Box<dyn DynCommandBuffer>],
769        dependencies: &[&dyn DynAccelerationStructure],
770    ) {
771        let command_buffers: Vec<&<C::A as Api>::CommandBuffer> = command_buffers
772            .iter()
773            .map(|command_buffer| command_buffer.expect_downcast_ref())
774            .collect();
775        let dependencies: Vec<&<C::A as Api>::AccelerationStructure> = dependencies
776            .iter()
777            .map(|dependency| dependency.expect_downcast_ref())
778            .collect();
779        unsafe { C::set_acceleration_structure_dependencies(&command_buffers, &dependencies) }
780    }
781}
782
783impl<'a> PassTimestampWrites<'a, dyn DynQuerySet> {
784    pub fn expect_downcast<B: DynQuerySet>(&self) -> PassTimestampWrites<'a, B> {
785        PassTimestampWrites {
786            query_set: self.query_set.expect_downcast_ref(),
787            beginning_of_pass_write_index: self.beginning_of_pass_write_index,
788            end_of_pass_write_index: self.end_of_pass_write_index,
789        }
790    }
791}
792
793impl<'a> Attachment<'a, dyn DynTextureView> {
794    pub fn expect_downcast<B: DynTextureView>(&self) -> Attachment<'a, B> {
795        Attachment {
796            view: self.view.expect_downcast_ref(),
797            usage: self.usage,
798        }
799    }
800}
801
802impl<'a> ColorAttachment<'a, dyn DynTextureView> {
803    pub fn expect_downcast<B: DynTextureView>(&self) -> ColorAttachment<'a, B> {
804        ColorAttachment {
805            target: self.target.expect_downcast(),
806            depth_slice: self.depth_slice,
807            resolve_target: self.resolve_target.as_ref().map(|rt| rt.expect_downcast()),
808            ops: self.ops,
809            clear_value: self.clear_value,
810        }
811    }
812}
813
814impl<'a> DepthStencilAttachment<'a, dyn DynTextureView> {
815    pub fn expect_downcast<B: DynTextureView>(&self) -> DepthStencilAttachment<'a, B> {
816        DepthStencilAttachment {
817            target: self.target.expect_downcast(),
818            depth_ops: self.depth_ops,
819            stencil_ops: self.stencil_ops,
820            clear_value: self.clear_value,
821        }
822    }
823}