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, Label, MemoryRange,
8    PassTimestampWrites, Rect, RenderPassDescriptor, TextureBarrier, TextureCopy,
9};
10
11use super::{
12    DynAccelerationStructure, DynBindGroup, DynBuffer, DynCommandBuffer, DynComputePipeline,
13    DynPipelineLayout, DynQuerySet, DynRenderPipeline, DynResource, DynResourceExt as _,
14    DynTexture, DynTextureView,
15};
16
17pub trait DynCommandEncoder: DynResource + core::fmt::Debug {
18    unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError>;
19
20    unsafe fn discard_encoding(&mut self);
21
22    unsafe fn end_encoding(&mut self) -> Result<Box<dyn DynCommandBuffer>, DeviceError>;
23
24    unsafe fn reset_all(&mut self, command_buffers: Vec<Box<dyn DynCommandBuffer>>);
25
26    unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]);
27    unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]);
28
29    unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange);
30
31    unsafe fn copy_buffer_to_buffer(
32        &mut self,
33        src: &dyn DynBuffer,
34        dst: &dyn DynBuffer,
35        regions: &[BufferCopy],
36    );
37
38    unsafe fn copy_texture_to_texture(
39        &mut self,
40        src: &dyn DynTexture,
41        src_usage: wgt::TextureUses,
42        dst: &dyn DynTexture,
43        regions: &[TextureCopy],
44    );
45
46    unsafe fn copy_buffer_to_texture(
47        &mut self,
48        src: &dyn DynBuffer,
49        dst: &dyn DynTexture,
50        regions: &[BufferTextureCopy],
51    );
52
53    unsafe fn copy_texture_to_buffer(
54        &mut self,
55        src: &dyn DynTexture,
56        src_usage: wgt::TextureUses,
57        dst: &dyn DynBuffer,
58        regions: &[BufferTextureCopy],
59    );
60
61    unsafe fn set_bind_group(
62        &mut self,
63        layout: &dyn DynPipelineLayout,
64        index: u32,
65        group: Option<&dyn DynBindGroup>,
66        dynamic_offsets: &[wgt::DynamicOffset],
67    );
68
69    unsafe fn set_push_constants(
70        &mut self,
71        layout: &dyn DynPipelineLayout,
72        stages: wgt::ShaderStages,
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    );
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(&mut self, count: [u32; 3]);
188    unsafe fn dispatch_indirect(&mut self, buffer: &dyn DynBuffer, offset: wgt::BufferAddress);
189
190    unsafe fn build_acceleration_structures<'a>(
191        &mut self,
192        descriptors: &'a [BuildAccelerationStructureDescriptor<
193            'a,
194            dyn DynBuffer,
195            dyn DynAccelerationStructure,
196        >],
197    );
198
199    unsafe fn place_acceleration_structure_barrier(
200        &mut self,
201        barrier: AccelerationStructureBarrier,
202    );
203
204    unsafe fn copy_acceleration_structure_to_acceleration_structure(
205        &mut self,
206        src: &dyn DynAccelerationStructure,
207        dst: &dyn DynAccelerationStructure,
208        copy: wgt::AccelerationStructureCopy,
209    );
210    unsafe fn read_acceleration_structure_compact_size(
211        &mut self,
212        acceleration_structure: &dyn DynAccelerationStructure,
213        buf: &dyn DynBuffer,
214    );
215}
216
217impl<C: CommandEncoder + DynResource> DynCommandEncoder for C {
218    unsafe fn begin_encoding(&mut self, label: Label) -> Result<(), DeviceError> {
219        unsafe { C::begin_encoding(self, label) }
220    }
221
222    unsafe fn discard_encoding(&mut self) {
223        unsafe { C::discard_encoding(self) }
224    }
225
226    unsafe fn end_encoding(&mut self) -> Result<Box<dyn DynCommandBuffer>, DeviceError> {
227        unsafe { C::end_encoding(self) }.map(|cb| {
228            let boxed_command_buffer: Box<<C::A as Api>::CommandBuffer> = Box::new(cb);
229            let boxed_command_buffer: Box<dyn DynCommandBuffer> = boxed_command_buffer;
230            boxed_command_buffer
231        })
232    }
233
234    unsafe fn reset_all(&mut self, command_buffers: Vec<Box<dyn DynCommandBuffer>>) {
235        unsafe { C::reset_all(self, command_buffers.into_iter().map(|cb| cb.unbox())) }
236    }
237
238    unsafe fn transition_buffers(&mut self, barriers: &[BufferBarrier<'_, dyn DynBuffer>]) {
239        let barriers = barriers.iter().map(|barrier| BufferBarrier {
240            buffer: barrier.buffer.expect_downcast_ref(),
241            usage: barrier.usage.clone(),
242        });
243        unsafe { self.transition_buffers(barriers) };
244    }
245
246    unsafe fn transition_textures(&mut self, barriers: &[TextureBarrier<'_, dyn DynTexture>]) {
247        let barriers = barriers.iter().map(|barrier| TextureBarrier {
248            texture: barrier.texture.expect_downcast_ref(),
249            usage: barrier.usage.clone(),
250            range: barrier.range,
251        });
252        unsafe { self.transition_textures(barriers) };
253    }
254
255    unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange) {
256        let buffer = buffer.expect_downcast_ref();
257        unsafe { C::clear_buffer(self, buffer, range) };
258    }
259
260    unsafe fn copy_buffer_to_buffer(
261        &mut self,
262        src: &dyn DynBuffer,
263        dst: &dyn DynBuffer,
264        regions: &[BufferCopy],
265    ) {
266        let src = src.expect_downcast_ref();
267        let dst = dst.expect_downcast_ref();
268        unsafe {
269            C::copy_buffer_to_buffer(self, src, dst, regions.iter().copied());
270        }
271    }
272
273    unsafe fn copy_texture_to_texture(
274        &mut self,
275        src: &dyn DynTexture,
276        src_usage: wgt::TextureUses,
277        dst: &dyn DynTexture,
278        regions: &[TextureCopy],
279    ) {
280        let src = src.expect_downcast_ref();
281        let dst = dst.expect_downcast_ref();
282        unsafe {
283            C::copy_texture_to_texture(self, src, src_usage, dst, regions.iter().cloned());
284        }
285    }
286
287    unsafe fn copy_buffer_to_texture(
288        &mut self,
289        src: &dyn DynBuffer,
290        dst: &dyn DynTexture,
291        regions: &[BufferTextureCopy],
292    ) {
293        let src = src.expect_downcast_ref();
294        let dst = dst.expect_downcast_ref();
295        unsafe {
296            C::copy_buffer_to_texture(self, src, dst, regions.iter().cloned());
297        }
298    }
299
300    unsafe fn copy_texture_to_buffer(
301        &mut self,
302        src: &dyn DynTexture,
303        src_usage: wgt::TextureUses,
304        dst: &dyn DynBuffer,
305        regions: &[BufferTextureCopy],
306    ) {
307        let src = src.expect_downcast_ref();
308        let dst = dst.expect_downcast_ref();
309        unsafe {
310            C::copy_texture_to_buffer(self, src, src_usage, dst, regions.iter().cloned());
311        }
312    }
313
314    unsafe fn set_bind_group(
315        &mut self,
316        layout: &dyn DynPipelineLayout,
317        index: u32,
318        group: Option<&dyn DynBindGroup>,
319        dynamic_offsets: &[wgt::DynamicOffset],
320    ) {
321        if group.is_none() {
322            // TODO: Handle group None correctly.
323            return;
324        }
325        let group = group.unwrap();
326
327        let layout = layout.expect_downcast_ref();
328        let group = group.expect_downcast_ref();
329        unsafe { C::set_bind_group(self, layout, index, group, dynamic_offsets) };
330    }
331
332    unsafe fn set_push_constants(
333        &mut self,
334        layout: &dyn DynPipelineLayout,
335        stages: wgt::ShaderStages,
336        offset_bytes: u32,
337        data: &[u32],
338    ) {
339        let layout = layout.expect_downcast_ref();
340        unsafe { C::set_push_constants(self, layout, stages, offset_bytes, data) };
341    }
342
343    unsafe fn insert_debug_marker(&mut self, label: &str) {
344        unsafe {
345            C::insert_debug_marker(self, label);
346        }
347    }
348
349    unsafe fn begin_debug_marker(&mut self, group_label: &str) {
350        unsafe {
351            C::begin_debug_marker(self, group_label);
352        }
353    }
354
355    unsafe fn end_debug_marker(&mut self) {
356        unsafe {
357            C::end_debug_marker(self);
358        }
359    }
360
361    unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32) {
362        let set = set.expect_downcast_ref();
363        unsafe { C::begin_query(self, set, index) };
364    }
365
366    unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32) {
367        let set = set.expect_downcast_ref();
368        unsafe { C::end_query(self, set, index) };
369    }
370
371    unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32) {
372        let set = set.expect_downcast_ref();
373        unsafe { C::write_timestamp(self, set, index) };
374    }
375
376    unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range<u32>) {
377        let set = set.expect_downcast_ref();
378        unsafe { C::reset_queries(self, set, range) };
379    }
380
381    unsafe fn copy_query_results(
382        &mut self,
383        set: &dyn DynQuerySet,
384        range: Range<u32>,
385        buffer: &dyn DynBuffer,
386        offset: wgt::BufferAddress,
387        stride: wgt::BufferSize,
388    ) {
389        let set = set.expect_downcast_ref();
390        let buffer = buffer.expect_downcast_ref();
391        unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) };
392    }
393
394    unsafe fn begin_render_pass(
395        &mut self,
396        desc: &RenderPassDescriptor<dyn DynQuerySet, dyn DynTextureView>,
397    ) {
398        let color_attachments = desc
399            .color_attachments
400            .iter()
401            .map(|attachment| {
402                attachment
403                    .as_ref()
404                    .map(|attachment| attachment.expect_downcast())
405            })
406            .collect::<Vec<_>>();
407
408        let desc: RenderPassDescriptor<<C::A as Api>::QuerySet, <C::A as Api>::TextureView> =
409            RenderPassDescriptor {
410                label: desc.label,
411                extent: desc.extent,
412                sample_count: desc.sample_count,
413                color_attachments: &color_attachments,
414                depth_stencil_attachment: desc
415                    .depth_stencil_attachment
416                    .as_ref()
417                    .map(|ds| ds.expect_downcast()),
418                multiview: desc.multiview,
419                timestamp_writes: desc
420                    .timestamp_writes
421                    .as_ref()
422                    .map(|writes| writes.expect_downcast()),
423                occlusion_query_set: desc
424                    .occlusion_query_set
425                    .map(|set| set.expect_downcast_ref()),
426            };
427        unsafe { C::begin_render_pass(self, &desc) };
428    }
429
430    unsafe fn end_render_pass(&mut self) {
431        unsafe {
432            C::end_render_pass(self);
433        }
434    }
435
436    unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>) {
437        unsafe {
438            C::set_viewport(self, rect, depth_range);
439        }
440    }
441
442    unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>) {
443        unsafe {
444            C::set_scissor_rect(self, rect);
445        }
446    }
447
448    unsafe fn set_stencil_reference(&mut self, value: u32) {
449        unsafe {
450            C::set_stencil_reference(self, value);
451        }
452    }
453
454    unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {
455        unsafe { C::set_blend_constants(self, color) };
456    }
457
458    unsafe fn draw(
459        &mut self,
460        first_vertex: u32,
461        vertex_count: u32,
462        first_instance: u32,
463        instance_count: u32,
464    ) {
465        unsafe {
466            C::draw(
467                self,
468                first_vertex,
469                vertex_count,
470                first_instance,
471                instance_count,
472            )
473        };
474    }
475
476    unsafe fn draw_indexed(
477        &mut self,
478        first_index: u32,
479        index_count: u32,
480        base_vertex: i32,
481        first_instance: u32,
482        instance_count: u32,
483    ) {
484        unsafe {
485            C::draw_indexed(
486                self,
487                first_index,
488                index_count,
489                base_vertex,
490                first_instance,
491                instance_count,
492            )
493        };
494    }
495
496    unsafe fn draw_mesh_tasks(
497        &mut self,
498        group_count_x: u32,
499        group_count_y: u32,
500        group_count_z: u32,
501    ) {
502        unsafe { C::draw_mesh_tasks(self, group_count_x, group_count_y, group_count_z) };
503    }
504
505    unsafe fn draw_indirect(
506        &mut self,
507        buffer: &dyn DynBuffer,
508        offset: wgt::BufferAddress,
509        draw_count: u32,
510    ) {
511        let buffer = buffer.expect_downcast_ref();
512        unsafe { C::draw_indirect(self, buffer, offset, draw_count) };
513    }
514
515    unsafe fn draw_indexed_indirect(
516        &mut self,
517        buffer: &dyn DynBuffer,
518        offset: wgt::BufferAddress,
519        draw_count: u32,
520    ) {
521        let buffer = buffer.expect_downcast_ref();
522        unsafe { C::draw_indexed_indirect(self, buffer, offset, draw_count) };
523    }
524
525    unsafe fn draw_mesh_tasks_indirect(
526        &mut self,
527        buffer: &dyn DynBuffer,
528        offset: wgt::BufferAddress,
529        draw_count: u32,
530    ) {
531        let buffer = buffer.expect_downcast_ref();
532        unsafe { C::draw_mesh_tasks_indirect(self, buffer, offset, draw_count) };
533    }
534
535    unsafe fn draw_indirect_count(
536        &mut self,
537        buffer: &dyn DynBuffer,
538        offset: wgt::BufferAddress,
539        count_buffer: &dyn DynBuffer,
540        count_offset: wgt::BufferAddress,
541        max_count: u32,
542    ) {
543        let buffer = buffer.expect_downcast_ref();
544        let count_buffer = count_buffer.expect_downcast_ref();
545        unsafe {
546            C::draw_indirect_count(self, buffer, offset, count_buffer, count_offset, max_count)
547        };
548    }
549
550    unsafe fn draw_indexed_indirect_count(
551        &mut self,
552        buffer: &dyn DynBuffer,
553        offset: wgt::BufferAddress,
554        count_buffer: &dyn DynBuffer,
555        count_offset: wgt::BufferAddress,
556        max_count: u32,
557    ) {
558        let buffer = buffer.expect_downcast_ref();
559        let count_buffer = count_buffer.expect_downcast_ref();
560        unsafe {
561            C::draw_indexed_indirect_count(
562                self,
563                buffer,
564                offset,
565                count_buffer,
566                count_offset,
567                max_count,
568            )
569        };
570    }
571
572    unsafe fn draw_mesh_tasks_indirect_count(
573        &mut self,
574        buffer: &dyn DynBuffer,
575        offset: wgt::BufferAddress,
576        count_buffer: &dyn DynBuffer,
577        count_offset: wgt::BufferAddress,
578        max_count: u32,
579    ) {
580        let buffer = buffer.expect_downcast_ref();
581        let count_buffer = count_buffer.expect_downcast_ref();
582        unsafe {
583            C::draw_mesh_tasks_indirect_count(
584                self,
585                buffer,
586                offset,
587                count_buffer,
588                count_offset,
589                max_count,
590            )
591        };
592    }
593
594    unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<dyn DynQuerySet>) {
595        let desc = ComputePassDescriptor {
596            label: desc.label,
597            timestamp_writes: desc
598                .timestamp_writes
599                .as_ref()
600                .map(|writes| writes.expect_downcast()),
601        };
602        unsafe { C::begin_compute_pass(self, &desc) };
603    }
604
605    unsafe fn end_compute_pass(&mut self) {
606        unsafe { C::end_compute_pass(self) };
607    }
608
609    unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline) {
610        let pipeline = pipeline.expect_downcast_ref();
611        unsafe { C::set_compute_pipeline(self, pipeline) };
612    }
613
614    unsafe fn dispatch(&mut self, count: [u32; 3]) {
615        unsafe { C::dispatch(self, count) };
616    }
617
618    unsafe fn dispatch_indirect(&mut self, buffer: &dyn DynBuffer, offset: wgt::BufferAddress) {
619        let buffer = buffer.expect_downcast_ref();
620        unsafe { C::dispatch_indirect(self, buffer, offset) };
621    }
622
623    unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline) {
624        let pipeline = pipeline.expect_downcast_ref();
625        unsafe { C::set_render_pipeline(self, pipeline) };
626    }
627
628    unsafe fn set_index_buffer<'a>(
629        &mut self,
630        binding: BufferBinding<'a, dyn DynBuffer>,
631        format: wgt::IndexFormat,
632    ) {
633        let binding = binding.expect_downcast();
634        unsafe { self.set_index_buffer(binding, format) };
635    }
636
637    unsafe fn set_vertex_buffer<'a>(
638        &mut self,
639        index: u32,
640        binding: BufferBinding<'a, dyn DynBuffer>,
641    ) {
642        let binding = binding.expect_downcast();
643        unsafe { self.set_vertex_buffer(index, binding) };
644    }
645
646    unsafe fn build_acceleration_structures<'a>(
647        &mut self,
648        descriptors: &'a [BuildAccelerationStructureDescriptor<
649            'a,
650            dyn DynBuffer,
651            dyn DynAccelerationStructure,
652        >],
653    ) {
654        // Need to collect entries here so we can reference them in the descriptor.
655        // TODO: API should be redesigned to avoid this and other descriptor copies that happen due to the dyn api.
656        let descriptor_entries = descriptors
657            .iter()
658            .map(|d| d.entries.expect_downcast())
659            .collect::<Vec<_>>();
660        let descriptors = descriptors
661            .iter()
662            .zip(descriptor_entries.iter())
663            .map(|(d, entries)| BuildAccelerationStructureDescriptor::<
664                <C::A as Api>::Buffer,
665                <C::A as Api>::AccelerationStructure,
666            > {
667                entries,
668                mode: d.mode,
669                flags: d.flags,
670                source_acceleration_structure: d
671                    .source_acceleration_structure
672                    .map(|a| a.expect_downcast_ref()),
673                destination_acceleration_structure: d
674                    .destination_acceleration_structure
675                    .expect_downcast_ref(),
676                scratch_buffer: d.scratch_buffer.expect_downcast_ref(),
677                scratch_buffer_offset: d.scratch_buffer_offset,
678            });
679        unsafe { C::build_acceleration_structures(self, descriptors.len() as _, descriptors) };
680    }
681
682    unsafe fn place_acceleration_structure_barrier(
683        &mut self,
684        barrier: AccelerationStructureBarrier,
685    ) {
686        unsafe { C::place_acceleration_structure_barrier(self, barrier) };
687    }
688
689    unsafe fn copy_acceleration_structure_to_acceleration_structure(
690        &mut self,
691        src: &dyn DynAccelerationStructure,
692        dst: &dyn DynAccelerationStructure,
693        copy: wgt::AccelerationStructureCopy,
694    ) {
695        let src = src.expect_downcast_ref();
696        let dst = dst.expect_downcast_ref();
697        unsafe { C::copy_acceleration_structure_to_acceleration_structure(self, src, dst, copy) };
698    }
699    unsafe fn read_acceleration_structure_compact_size(
700        &mut self,
701        acceleration_structure: &dyn DynAccelerationStructure,
702        buf: &dyn DynBuffer,
703    ) {
704        let acceleration_structure = acceleration_structure.expect_downcast_ref();
705        let buf = buf.expect_downcast_ref();
706        unsafe { C::read_acceleration_structure_compact_size(self, acceleration_structure, buf) }
707    }
708}
709
710impl<'a> PassTimestampWrites<'a, dyn DynQuerySet> {
711    pub fn expect_downcast<B: DynQuerySet>(&self) -> PassTimestampWrites<'a, B> {
712        PassTimestampWrites {
713            query_set: self.query_set.expect_downcast_ref(),
714            beginning_of_pass_write_index: self.beginning_of_pass_write_index,
715            end_of_pass_write_index: self.end_of_pass_write_index,
716        }
717    }
718}
719
720impl<'a> Attachment<'a, dyn DynTextureView> {
721    pub fn expect_downcast<B: DynTextureView>(&self) -> Attachment<'a, B> {
722        Attachment {
723            view: self.view.expect_downcast_ref(),
724            usage: self.usage,
725        }
726    }
727}
728
729impl<'a> ColorAttachment<'a, dyn DynTextureView> {
730    pub fn expect_downcast<B: DynTextureView>(&self) -> ColorAttachment<'a, B> {
731        ColorAttachment {
732            target: self.target.expect_downcast(),
733            resolve_target: self.resolve_target.as_ref().map(|rt| rt.expect_downcast()),
734            ops: self.ops,
735            clear_value: self.clear_value,
736        }
737    }
738}
739
740impl<'a> DepthStencilAttachment<'a, dyn DynTextureView> {
741    pub fn expect_downcast<B: DynTextureView>(&self) -> DepthStencilAttachment<'a, B> {
742        DepthStencilAttachment {
743            target: self.target.expect_downcast(),
744            depth_ops: self.depth_ops,
745            stencil_ops: self.stencil_ops,
746            clear_value: self.clear_value,
747        }
748    }
749}