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