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 queue_family_ownership_transfer: barrier.queue_family_ownership_transfer,
272 });
273 unsafe { self.transition_textures(barriers) };
274 }
275
276 unsafe fn clear_buffer(&mut self, buffer: &dyn DynBuffer, range: MemoryRange) {
277 let buffer = buffer.expect_downcast_ref();
278 unsafe { C::clear_buffer(self, buffer, range) };
279 }
280
281 unsafe fn copy_buffer_to_buffer(
282 &mut self,
283 src: &dyn DynBuffer,
284 dst: &dyn DynBuffer,
285 regions: &[BufferCopy],
286 ) {
287 let src = src.expect_downcast_ref();
288 let dst = dst.expect_downcast_ref();
289 unsafe {
290 C::copy_buffer_to_buffer(self, src, dst, regions.iter().copied());
291 }
292 }
293
294 unsafe fn copy_texture_to_texture(
295 &mut self,
296 src: &dyn DynTexture,
297 src_usage: wgt::TextureUses,
298 dst: &dyn DynTexture,
299 regions: &[TextureCopy],
300 ) {
301 let src = src.expect_downcast_ref();
302 let dst = dst.expect_downcast_ref();
303 unsafe {
304 C::copy_texture_to_texture(self, src, src_usage, dst, regions.iter().cloned());
305 }
306 }
307
308 unsafe fn copy_buffer_to_texture(
309 &mut self,
310 src: &dyn DynBuffer,
311 dst: &dyn DynTexture,
312 regions: &[BufferTextureCopy],
313 ) {
314 let src = src.expect_downcast_ref();
315 let dst = dst.expect_downcast_ref();
316 unsafe {
317 C::copy_buffer_to_texture(self, src, dst, regions.iter().cloned());
318 }
319 }
320
321 unsafe fn copy_texture_to_buffer(
322 &mut self,
323 src: &dyn DynTexture,
324 src_usage: wgt::TextureUses,
325 dst: &dyn DynBuffer,
326 regions: &[BufferTextureCopy],
327 ) {
328 let src = src.expect_downcast_ref();
329 let dst = dst.expect_downcast_ref();
330 unsafe {
331 C::copy_texture_to_buffer(self, src, src_usage, dst, regions.iter().cloned());
332 }
333 }
334
335 unsafe fn set_bind_group(
336 &mut self,
337 layout: &dyn DynPipelineLayout,
338 index: u32,
339 group: &dyn DynBindGroup,
340 dynamic_offsets: &[wgt::DynamicOffset],
341 ) {
342 let layout = layout.expect_downcast_ref();
343 let group = group.expect_downcast_ref();
344 unsafe { C::set_bind_group(self, layout, index, group, dynamic_offsets) };
345 }
346
347 unsafe fn set_immediates(
348 &mut self,
349 layout: &dyn DynPipelineLayout,
350 offset_bytes: u32,
351 data: &[u32],
352 ) {
353 let layout = layout.expect_downcast_ref();
354 unsafe { C::set_immediates(self, layout, offset_bytes, data) };
355 }
356
357 unsafe fn insert_debug_marker(&mut self, label: &str) {
358 unsafe {
359 C::insert_debug_marker(self, label);
360 }
361 }
362
363 unsafe fn begin_debug_marker(&mut self, group_label: &str) {
364 unsafe {
365 C::begin_debug_marker(self, group_label);
366 }
367 }
368
369 unsafe fn end_debug_marker(&mut self) {
370 unsafe {
371 C::end_debug_marker(self);
372 }
373 }
374
375 unsafe fn begin_query(&mut self, set: &dyn DynQuerySet, index: u32) {
376 let set = set.expect_downcast_ref();
377 unsafe { C::begin_query(self, set, index) };
378 }
379
380 unsafe fn end_query(&mut self, set: &dyn DynQuerySet, index: u32) {
381 let set = set.expect_downcast_ref();
382 unsafe { C::end_query(self, set, index) };
383 }
384
385 unsafe fn write_timestamp(&mut self, set: &dyn DynQuerySet, index: u32) {
386 let set = set.expect_downcast_ref();
387 unsafe { C::write_timestamp(self, set, index) };
388 }
389
390 unsafe fn reset_queries(&mut self, set: &dyn DynQuerySet, range: Range<u32>) {
391 let set = set.expect_downcast_ref();
392 unsafe { C::reset_queries(self, set, range) };
393 }
394
395 unsafe fn copy_query_results(
396 &mut self,
397 set: &dyn DynQuerySet,
398 range: Range<u32>,
399 buffer: &dyn DynBuffer,
400 offset: wgt::BufferAddress,
401 stride: wgt::BufferSize,
402 ) {
403 let set = set.expect_downcast_ref();
404 let buffer = buffer.expect_downcast_ref();
405 unsafe { C::copy_query_results(self, set, range, buffer, offset, stride) };
406 }
407
408 unsafe fn begin_render_pass(
409 &mut self,
410 desc: &RenderPassDescriptor<dyn DynQuerySet, dyn DynTextureView>,
411 ) -> Result<(), DeviceError> {
412 let color_attachments = desc
413 .color_attachments
414 .iter()
415 .map(|attachment| {
416 attachment
417 .as_ref()
418 .map(|attachment| attachment.expect_downcast())
419 })
420 .collect::<Vec<_>>();
421
422 let desc: RenderPassDescriptor<<C::A as Api>::QuerySet, <C::A as Api>::TextureView> =
423 RenderPassDescriptor {
424 label: desc.label,
425 extent: desc.extent,
426 sample_count: desc.sample_count,
427 color_attachments: &color_attachments,
428 depth_stencil_attachment: desc
429 .depth_stencil_attachment
430 .as_ref()
431 .map(|ds| ds.expect_downcast()),
432 multiview_mask: desc.multiview_mask,
433 timestamp_writes: desc
434 .timestamp_writes
435 .as_ref()
436 .map(|writes| writes.expect_downcast()),
437 occlusion_query_set: desc
438 .occlusion_query_set
439 .map(|set| set.expect_downcast_ref()),
440 };
441 unsafe { C::begin_render_pass(self, &desc) }
442 }
443
444 unsafe fn end_render_pass(&mut self) {
445 unsafe {
446 C::end_render_pass(self);
447 }
448 }
449
450 unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>) {
451 unsafe {
452 C::set_viewport(self, rect, depth_range);
453 }
454 }
455
456 unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>) {
457 unsafe {
458 C::set_scissor_rect(self, rect);
459 }
460 }
461
462 unsafe fn set_stencil_reference(&mut self, value: u32) {
463 unsafe {
464 C::set_stencil_reference(self, value);
465 }
466 }
467
468 unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) {
469 unsafe { C::set_blend_constants(self, color) };
470 }
471
472 unsafe fn draw(
473 &mut self,
474 first_vertex: u32,
475 vertex_count: u32,
476 first_instance: u32,
477 instance_count: u32,
478 ) {
479 unsafe {
480 C::draw(
481 self,
482 first_vertex,
483 vertex_count,
484 first_instance,
485 instance_count,
486 )
487 };
488 }
489
490 unsafe fn draw_indexed(
491 &mut self,
492 first_index: u32,
493 index_count: u32,
494 base_vertex: i32,
495 first_instance: u32,
496 instance_count: u32,
497 ) {
498 unsafe {
499 C::draw_indexed(
500 self,
501 first_index,
502 index_count,
503 base_vertex,
504 first_instance,
505 instance_count,
506 )
507 };
508 }
509
510 unsafe fn draw_mesh_tasks(
511 &mut self,
512 group_count_x: u32,
513 group_count_y: u32,
514 group_count_z: u32,
515 ) {
516 unsafe { C::draw_mesh_tasks(self, group_count_x, group_count_y, group_count_z) };
517 }
518
519 unsafe fn draw_indirect(
520 &mut self,
521 buffer: &dyn DynBuffer,
522 offset: wgt::BufferAddress,
523 draw_count: u32,
524 ) {
525 let buffer = buffer.expect_downcast_ref();
526 unsafe { C::draw_indirect(self, buffer, offset, draw_count) };
527 }
528
529 unsafe fn draw_indexed_indirect(
530 &mut self,
531 buffer: &dyn DynBuffer,
532 offset: wgt::BufferAddress,
533 draw_count: u32,
534 ) {
535 let buffer = buffer.expect_downcast_ref();
536 unsafe { C::draw_indexed_indirect(self, buffer, offset, draw_count) };
537 }
538
539 unsafe fn draw_mesh_tasks_indirect(
540 &mut self,
541 buffer: &dyn DynBuffer,
542 offset: wgt::BufferAddress,
543 draw_count: u32,
544 ) {
545 let buffer = buffer.expect_downcast_ref();
546 unsafe { C::draw_mesh_tasks_indirect(self, buffer, offset, draw_count) };
547 }
548
549 unsafe fn draw_indirect_count(
550 &mut self,
551 buffer: &dyn DynBuffer,
552 offset: wgt::BufferAddress,
553 count_buffer: &dyn DynBuffer,
554 count_offset: wgt::BufferAddress,
555 max_count: u32,
556 ) {
557 let buffer = buffer.expect_downcast_ref();
558 let count_buffer = count_buffer.expect_downcast_ref();
559 unsafe {
560 C::draw_indirect_count(self, buffer, offset, count_buffer, count_offset, max_count)
561 };
562 }
563
564 unsafe fn draw_indexed_indirect_count(
565 &mut self,
566 buffer: &dyn DynBuffer,
567 offset: wgt::BufferAddress,
568 count_buffer: &dyn DynBuffer,
569 count_offset: wgt::BufferAddress,
570 max_count: u32,
571 ) {
572 let buffer = buffer.expect_downcast_ref();
573 let count_buffer = count_buffer.expect_downcast_ref();
574 unsafe {
575 C::draw_indexed_indirect_count(
576 self,
577 buffer,
578 offset,
579 count_buffer,
580 count_offset,
581 max_count,
582 )
583 };
584 }
585
586 unsafe fn draw_mesh_tasks_indirect_count(
587 &mut self,
588 buffer: &dyn DynBuffer,
589 offset: wgt::BufferAddress,
590 count_buffer: &dyn DynBuffer,
591 count_offset: wgt::BufferAddress,
592 max_count: u32,
593 ) {
594 let buffer = buffer.expect_downcast_ref();
595 let count_buffer = count_buffer.expect_downcast_ref();
596 unsafe {
597 C::draw_mesh_tasks_indirect_count(
598 self,
599 buffer,
600 offset,
601 count_buffer,
602 count_offset,
603 max_count,
604 )
605 };
606 }
607
608 unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<dyn DynQuerySet>) {
609 let desc = ComputePassDescriptor {
610 label: desc.label,
611 timestamp_writes: desc
612 .timestamp_writes
613 .as_ref()
614 .map(|writes| writes.expect_downcast()),
615 };
616 unsafe { C::begin_compute_pass(self, &desc) };
617 }
618
619 unsafe fn end_compute_pass(&mut self) {
620 unsafe { C::end_compute_pass(self) };
621 }
622
623 unsafe fn set_compute_pipeline(&mut self, pipeline: &dyn DynComputePipeline) {
624 let pipeline = pipeline.expect_downcast_ref();
625 unsafe { C::set_compute_pipeline(self, pipeline) };
626 }
627
628 unsafe fn dispatch_workgroups(&mut self, count: [u32; 3]) {
629 unsafe { C::dispatch_workgroups(self, count) };
630 }
631
632 unsafe fn dispatch_workgroups_indirect(
633 &mut self,
634 buffer: &dyn DynBuffer,
635 offset: wgt::BufferAddress,
636 ) {
637 let buffer = buffer.expect_downcast_ref();
638 unsafe { C::dispatch_workgroups_indirect(self, buffer, offset) };
639 }
640
641 unsafe fn set_render_pipeline(&mut self, pipeline: &dyn DynRenderPipeline) {
642 let pipeline = pipeline.expect_downcast_ref();
643 unsafe { C::set_render_pipeline(self, pipeline) };
644 }
645
646 unsafe fn set_index_buffer<'a>(
647 &mut self,
648 binding: BufferBinding<'a, dyn DynBuffer>,
649 format: wgt::IndexFormat,
650 ) {
651 let binding = binding.expect_downcast();
652 unsafe { self.set_index_buffer(binding, format) };
653 }
654
655 unsafe fn set_vertex_buffer<'a>(
656 &mut self,
657 index: u32,
658 binding: BufferBinding<'a, dyn DynBuffer>,
659 ) {
660 let binding = binding.expect_downcast();
661 unsafe { self.set_vertex_buffer(index, binding) };
662 }
663
664 unsafe fn begin_ray_tracing_pass(&mut self, desc: &RayTracingPassDescriptor) {
665 let desc = RayTracingPassDescriptor { label: desc.label };
666 unsafe { C::begin_ray_tracing_pass(self, &desc) };
667 }
668
669 unsafe fn end_ray_tracing_pass(&mut self) {
670 unsafe { C::end_ray_tracing_pass(self) };
671 }
672
673 unsafe fn set_ray_tracing_pipeline(&mut self, pipeline: &dyn DynRayTracingPipeline) {
674 let pipeline = pipeline.expect_downcast_ref();
675 unsafe { C::set_ray_tracing_pipeline(self, pipeline) };
676 }
677
678 unsafe fn trace_rays<'a>(
679 &mut self,
680 count: [u32; 3],
681 ray_generation_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
682 miss_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
683 intersection_group_data: crate::PipelineGroupData<'a, dyn DynBuffer>,
684 ) {
685 let downcast_group_data =
686 |data: crate::PipelineGroupData<'a, dyn DynBuffer>| crate::PipelineGroupData {
687 buffer: data.buffer.expect_downcast_ref(),
688 offset: data.offset,
689 stride: data.stride,
690 count: data.count,
691 };
692
693 unsafe {
694 C::trace_rays(
695 self,
696 count,
697 downcast_group_data(ray_generation_group_data),
698 downcast_group_data(miss_group_data),
699 downcast_group_data(intersection_group_data),
700 );
701 }
702 }
703
704 unsafe fn build_acceleration_structures<'a>(
705 &mut self,
706 descriptors: &'a [BuildAccelerationStructureDescriptor<
707 'a,
708 dyn DynBuffer,
709 dyn DynAccelerationStructure,
710 >],
711 ) {
712 let descriptor_entries = descriptors
715 .iter()
716 .map(|d| d.entries.expect_downcast())
717 .collect::<Vec<_>>();
718 let descriptors = descriptors
719 .iter()
720 .zip(descriptor_entries.iter())
721 .map(|(d, entries)| BuildAccelerationStructureDescriptor::<
722 <C::A as Api>::Buffer,
723 <C::A as Api>::AccelerationStructure,
724 > {
725 entries,
726 mode: d.mode,
727 flags: d.flags,
728 source_acceleration_structure: d
729 .source_acceleration_structure
730 .map(|a| a.expect_downcast_ref()),
731 destination_acceleration_structure: d
732 .destination_acceleration_structure
733 .expect_downcast_ref(),
734 scratch_buffer: d.scratch_buffer.expect_downcast_ref(),
735 scratch_buffer_offset: d.scratch_buffer_offset,
736 });
737 unsafe { C::build_acceleration_structures(self, descriptors.len() as _, descriptors) };
738 }
739
740 unsafe fn place_acceleration_structure_barrier(
741 &mut self,
742 barrier: AccelerationStructureBarrier,
743 ) {
744 unsafe { C::place_acceleration_structure_barrier(self, barrier) };
745 }
746
747 unsafe fn copy_acceleration_structure_to_acceleration_structure(
748 &mut self,
749 src: &dyn DynAccelerationStructure,
750 dst: &dyn DynAccelerationStructure,
751 copy: wgt::AccelerationStructureCopy,
752 ) {
753 let src = src.expect_downcast_ref();
754 let dst = dst.expect_downcast_ref();
755 unsafe { C::copy_acceleration_structure_to_acceleration_structure(self, src, dst, copy) };
756 }
757 unsafe fn read_acceleration_structure_compact_size(
758 &mut self,
759 acceleration_structure: &dyn DynAccelerationStructure,
760 buf: &dyn DynBuffer,
761 ) {
762 let acceleration_structure = acceleration_structure.expect_downcast_ref();
763 let buf = buf.expect_downcast_ref();
764 unsafe { C::read_acceleration_structure_compact_size(self, acceleration_structure, buf) }
765 }
766
767 unsafe fn set_acceleration_structure_dependencies(
768 &self,
769 command_buffers: &[Box<dyn DynCommandBuffer>],
770 dependencies: &[&dyn DynAccelerationStructure],
771 ) {
772 let command_buffers: Vec<&<C::A as Api>::CommandBuffer> = command_buffers
773 .iter()
774 .map(|command_buffer| command_buffer.expect_downcast_ref())
775 .collect();
776 let dependencies: Vec<&<C::A as Api>::AccelerationStructure> = dependencies
777 .iter()
778 .map(|dependency| dependency.expect_downcast_ref())
779 .collect();
780 unsafe { C::set_acceleration_structure_dependencies(&command_buffers, &dependencies) }
781 }
782}
783
784impl<'a> PassTimestampWrites<'a, dyn DynQuerySet> {
785 pub fn expect_downcast<B: DynQuerySet>(&self) -> PassTimestampWrites<'a, B> {
786 PassTimestampWrites {
787 query_set: self.query_set.expect_downcast_ref(),
788 beginning_of_pass_write_index: self.beginning_of_pass_write_index,
789 end_of_pass_write_index: self.end_of_pass_write_index,
790 }
791 }
792}
793
794impl<'a> Attachment<'a, dyn DynTextureView> {
795 pub fn expect_downcast<B: DynTextureView>(&self) -> Attachment<'a, B> {
796 Attachment {
797 view: self.view.expect_downcast_ref(),
798 usage: self.usage,
799 }
800 }
801}
802
803impl<'a> ColorAttachment<'a, dyn DynTextureView> {
804 pub fn expect_downcast<B: DynTextureView>(&self) -> ColorAttachment<'a, B> {
805 ColorAttachment {
806 target: self.target.expect_downcast(),
807 depth_slice: self.depth_slice,
808 resolve_target: self.resolve_target.as_ref().map(|rt| rt.expect_downcast()),
809 ops: self.ops,
810 clear_value: self.clear_value,
811 }
812 }
813}
814
815impl<'a> DepthStencilAttachment<'a, dyn DynTextureView> {
816 pub fn expect_downcast<B: DynTextureView>(&self) -> DepthStencilAttachment<'a, B> {
817 DepthStencilAttachment {
818 target: self.target.expect_downcast(),
819 depth_ops: self.depth_ops,
820 stencil_ops: self.stencil_ops,
821 clear_value: self.clear_value,
822 }
823 }
824}