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 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 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}