vulkano_taskgraph/command_buffer/commands/pipeline.rs
1use crate::{
2 command_buffer::{RecordingCommandBuffer, Result},
3 Id,
4};
5#[cfg(doc)]
6use vulkano::command_buffer::{
7 DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand,
8 DrawMeshTasksIndirectCommand,
9};
10use vulkano::{
11 buffer::Buffer, device::DeviceOwned, pipeline::ray_tracing::ShaderBindingTableAddresses,
12 DeviceSize, Version, VulkanObject,
13};
14
15/// # Commands to execute a bound pipeline
16///
17/// Dispatch commands require a compute queue, draw commands require a graphics queue.
18impl RecordingCommandBuffer<'_> {
19 /// Performs a single compute operation using a compute pipeline.
20 ///
21 /// A compute pipeline must have been bound using [`bind_pipeline_compute`]. Any resources used
22 /// by the compute pipeline, such as descriptor sets, must have been set beforehand.
23 ///
24 /// # Safety
25 ///
26 /// - The general [shader safety requirements] apply.
27 ///
28 /// [`bind_pipeline_compute`]: Self::bind_pipeline_compute
29 /// [shader safety requirements]: vulkano::shader#safety
30 pub unsafe fn dispatch(&mut self, group_counts: [u32; 3]) -> Result<&mut Self> {
31 Ok(unsafe { self.dispatch_unchecked(group_counts) })
32 }
33
34 pub unsafe fn dispatch_unchecked(&mut self, group_counts: [u32; 3]) -> &mut Self {
35 let fns = self.device().fns();
36 unsafe {
37 (fns.v1_0.cmd_dispatch)(
38 self.handle(),
39 group_counts[0],
40 group_counts[1],
41 group_counts[2],
42 )
43 };
44
45 self
46 }
47
48 /// Performs a single compute operation using a compute pipeline. One dispatch is performed
49 /// for the [`DispatchIndirectCommand`] struct that is read from `buffer` starting at `offset`.
50 ///
51 /// A compute pipeline must have been bound using [`bind_pipeline_compute`]. Any resources used
52 /// by the compute pipeline, such as descriptor sets, must have been set beforehand.
53 ///
54 /// # Safety
55 ///
56 /// - The general [shader safety requirements] apply.
57 /// - The [safety requirements for `DispatchIndirectCommand`] apply.
58 ///
59 /// [`bind_pipeline_compute`]: Self::bind_pipeline_compute
60 /// [shader safety requirements]: vulkano::shader#safety
61 /// [safety requirements for `DispatchIndirectCommand`]: DispatchIndirectCommand#safety
62 pub unsafe fn dispatch_indirect(
63 &mut self,
64 buffer: Id<Buffer>,
65 offset: DeviceSize,
66 ) -> Result<&mut Self> {
67 Ok(unsafe { self.dispatch_indirect_unchecked(buffer, offset) })
68 }
69
70 pub unsafe fn dispatch_indirect_unchecked(
71 &mut self,
72 buffer: Id<Buffer>,
73 offset: DeviceSize,
74 ) -> &mut Self {
75 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
76
77 let fns = self.device().fns();
78 unsafe { (fns.v1_0.cmd_dispatch_indirect)(self.handle(), buffer.handle(), offset) };
79
80 self
81 }
82
83 /// Performs a single draw operation using a primitive shading graphics pipeline.
84 ///
85 /// The parameters specify the first vertex and the number of vertices to draw, and the first
86 /// instance and number of instances. For non-instanced drawing, specify `instance_count` as 1
87 /// and `first_instance` as 0.
88 ///
89 /// A primitive shading graphics pipeline must have been bound using
90 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
91 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
92 /// graphics pipeline uses vertex buffers, then the provided vertex and instance ranges must be
93 /// in range of the bound vertex buffers.
94 ///
95 /// # Safety
96 ///
97 /// - The general [shader safety requirements] apply.
98 ///
99 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
100 /// [shader safety requirements]: vulkano::shader#safety
101 pub unsafe fn draw(
102 &mut self,
103 vertex_count: u32,
104 instance_count: u32,
105 first_vertex: u32,
106 first_instance: u32,
107 ) -> Result<&mut Self> {
108 Ok(unsafe {
109 self.draw_unchecked(vertex_count, instance_count, first_vertex, first_instance)
110 })
111 }
112
113 pub unsafe fn draw_unchecked(
114 &mut self,
115 vertex_count: u32,
116 instance_count: u32,
117 first_vertex: u32,
118 first_instance: u32,
119 ) -> &mut Self {
120 let fns = self.device().fns();
121 unsafe {
122 (fns.v1_0.cmd_draw)(
123 self.handle(),
124 vertex_count,
125 instance_count,
126 first_vertex,
127 first_instance,
128 )
129 };
130
131 self
132 }
133
134 /// Performs multiple draw operations using a primitive shading graphics pipeline.
135 ///
136 /// One draw is performed for each [`DrawIndirectCommand`] struct that is read from `buffer`
137 /// starting at `offset`, with the offset increasing by `stride` bytes for each successive
138 /// draw. `draw_count` draw commands are performed. The maximum number of draw commands in the
139 /// buffer is limited by the [`max_draw_indirect_count`] limit. This limit is 1 unless the
140 /// [`multi_draw_indirect`] feature has been enabled.
141 ///
142 /// A primitive shading graphics pipeline must have been bound using
143 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
144 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
145 /// graphics pipeline uses vertex buffers, then the vertex and instance ranges of each
146 /// `DrawIndirectCommand` in the indirect buffer must be in range of the bound vertex buffers.
147 ///
148 /// # Safety
149 ///
150 /// - The general [shader safety requirements] apply.
151 /// - The [safety requirements for `DrawIndirectCommand`] apply.
152 ///
153 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
154 /// [`multi_draw_indirect`]: vulkano::device::DeviceFeatures::multi_draw_indirect
155 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
156 /// [shader safety requirements]: vulkano::shader#safety
157 /// [safety requirements for `DrawIndirectCommand`]: DrawIndirectCommand#safety
158 pub unsafe fn draw_indirect(
159 &mut self,
160 buffer: Id<Buffer>,
161 offset: DeviceSize,
162 draw_count: u32,
163 stride: u32,
164 ) -> Result<&mut Self> {
165 Ok(unsafe { self.draw_indirect_unchecked(buffer, offset, draw_count, stride) })
166 }
167
168 pub unsafe fn draw_indirect_unchecked(
169 &mut self,
170 buffer: Id<Buffer>,
171 offset: DeviceSize,
172 draw_count: u32,
173 stride: u32,
174 ) -> &mut Self {
175 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
176
177 let fns = self.device().fns();
178 unsafe {
179 (fns.v1_0.cmd_draw_indirect)(self.handle(), buffer.handle(), offset, draw_count, stride)
180 };
181
182 self
183 }
184
185 /// Performs multiple draw operations using a primitive shading graphics pipeline, reading the
186 /// number of draw operations from a separate buffer.
187 ///
188 /// One draw is performed for each [`DrawIndirectCommand`] struct that is read from `buffer`
189 /// starting at `offset`, with the offset increasing by `stride` bytes for each successive
190 /// draw. The number of draws to perform is read from `count_buffer` at `count_buffer_offset`,
191 /// or specified by `max_draw_count`, whichever is lower. This number is limited by the
192 /// [`max_draw_indirect_count`] limit.
193 ///
194 /// A primitive shading graphics pipeline must have been bound using
195 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
196 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
197 /// graphics pipeline uses vertex buffers, then the vertex and instance ranges of each
198 /// `DrawIndirectCommand` in the indirect buffer must be in range of the bound vertex buffers.
199 ///
200 /// # Safety
201 ///
202 /// - The general [shader safety requirements] apply.
203 /// - The [safety requirements for `DrawIndirectCommand`] apply.
204 /// - The count stored in `count_buffer` must not be greater than the
205 /// [`max_draw_indirect_count`] device limit.
206 /// - The count stored in `count_buffer` must fall within the range of `buffer` starting at
207 /// `offset`.
208 ///
209 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
210 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
211 /// [shader safety requirements]: vulkano::shader#safety
212 /// [safety requirements for `DrawIndirectCommand`]: DrawIndirectCommand#safety
213 pub unsafe fn draw_indirect_count(
214 &mut self,
215 buffer: Id<Buffer>,
216 offset: DeviceSize,
217 count_buffer: Id<Buffer>,
218 count_buffer_offset: DeviceSize,
219 max_draw_count: u32,
220 stride: u32,
221 ) -> Result<&mut Self> {
222 Ok(unsafe {
223 self.draw_indirect_count_unchecked(
224 buffer,
225 offset,
226 count_buffer,
227 count_buffer_offset,
228 max_draw_count,
229 stride,
230 )
231 })
232 }
233
234 pub unsafe fn draw_indirect_count_unchecked(
235 &mut self,
236 buffer: Id<Buffer>,
237 offset: DeviceSize,
238 count_buffer: Id<Buffer>,
239 count_buffer_offset: DeviceSize,
240 max_draw_count: u32,
241 stride: u32,
242 ) -> &mut Self {
243 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
244 let count_buffer = unsafe { self.accesses.buffer_unchecked(count_buffer) };
245
246 let device = self.device();
247 let fns = device.fns();
248 let cmd_draw_indirect_count = if device.api_version() >= Version::V1_2 {
249 fns.v1_2.cmd_draw_indirect_count
250 } else if device.enabled_extensions().khr_draw_indirect_count {
251 fns.khr_draw_indirect_count.cmd_draw_indirect_count_khr
252 } else if device.enabled_extensions().amd_draw_indirect_count {
253 fns.amd_draw_indirect_count.cmd_draw_indirect_count_amd
254 } else {
255 std::process::abort();
256 };
257
258 unsafe {
259 cmd_draw_indirect_count(
260 self.handle(),
261 buffer.handle(),
262 offset,
263 count_buffer.handle(),
264 count_buffer_offset,
265 max_draw_count,
266 stride,
267 )
268 };
269
270 self
271 }
272
273 /// Performs a single draw operation using a primitive shading graphics pipeline, using an
274 /// index buffer.
275 ///
276 /// The parameters specify the first index and the number of indices in the index buffer that
277 /// should be used, and the first instance and number of instances. For non-instanced drawing,
278 /// specify `instance_count` as 1 and `first_instance` as 0. The `vertex_offset` is a constant
279 /// value that should be added to each index in the index buffer to produce the final vertex
280 /// number to be used.
281 ///
282 /// An index buffer must have been bound using [`bind_index_buffer`], and the provided index
283 /// range must be in range of the bound index buffer.
284 ///
285 /// A primitive shading graphics pipeline must have been bound using
286 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
287 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
288 /// graphics pipeline uses vertex buffers, then the provided instance range must be in range of
289 /// the bound vertex buffers. The vertex indices in the index buffer must be in range of the
290 /// bound vertex buffers.
291 ///
292 /// # Safety
293 ///
294 /// - The general [shader safety requirements] apply.
295 /// - Every vertex number that is retrieved from the index buffer must fall within the range of
296 /// the bound vertex-rate vertex buffers.
297 /// - Every vertex number that is retrieved from the index buffer, if it is not the special
298 /// primitive restart value, must be no greater than the [`max_draw_indexed_index_value`]
299 /// device limit.
300 ///
301 /// [`bind_index_buffer`]: Self::bind_index_buffer
302 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
303 /// [shader safety requirements]: vulkano::shader#safety
304 /// [`max_draw_indexed_index_value`]: vulkano::device::DeviceProperties::max_draw_indexed_index_value
305 pub unsafe fn draw_indexed(
306 &mut self,
307 index_count: u32,
308 instance_count: u32,
309 first_index: u32,
310 vertex_offset: i32,
311 first_instance: u32,
312 ) -> Result<&mut Self> {
313 Ok(unsafe {
314 self.draw_indexed_unchecked(
315 index_count,
316 instance_count,
317 first_index,
318 vertex_offset,
319 first_instance,
320 )
321 })
322 }
323
324 pub unsafe fn draw_indexed_unchecked(
325 &mut self,
326 index_count: u32,
327 instance_count: u32,
328 first_index: u32,
329 vertex_offset: i32,
330 first_instance: u32,
331 ) -> &mut Self {
332 let fns = self.device().fns();
333 unsafe {
334 (fns.v1_0.cmd_draw_indexed)(
335 self.handle(),
336 index_count,
337 instance_count,
338 first_index,
339 vertex_offset,
340 first_instance,
341 )
342 };
343
344 self
345 }
346
347 /// Performs multiple draw operations using a primitive shading graphics pipeline, using an
348 /// index buffer.
349 ///
350 /// One draw is performed for each [`DrawIndexedIndirectCommand`] struct that is read from
351 /// `buffer` starting at `offset`, with the offset increasing by `stride` bytes with each
352 /// successive draw. `draw_count` draw commands are performed. The maximum number of draw
353 /// commands in the buffer is limited by the [`max_draw_indirect_count`] limit. This limit is 1
354 /// unless the [`multi_draw_indirect`] feature has been enabled.
355 ///
356 /// An index buffer must have been bound using [`bind_index_buffer`], and the index ranges of
357 /// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound
358 /// index buffer.
359 ///
360 /// A primitive shading graphics pipeline must have been bound using
361 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
362 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
363 /// graphics pipeline uses vertex buffers, then the instance ranges of each
364 /// `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound vertex
365 /// buffers.
366 ///
367 /// # Safety
368 ///
369 /// - The general [shader safety requirements] apply.
370 /// - The [safety requirements for `DrawIndexedIndirectCommand`] apply.
371 ///
372 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
373 /// [`multi_draw_indirect`]: vulkano::device::DeviceFeatures::multi_draw_indirect
374 /// [`bind_index_buffer`]: Self::bind_index_buffer
375 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
376 /// [shader safety requirements]: vulkano::shader#safety
377 /// [safety requirements for `DrawIndexedIndirectCommand`]: DrawIndexedIndirectCommand#safety
378 pub unsafe fn draw_indexed_indirect(
379 &mut self,
380 buffer: Id<Buffer>,
381 offset: DeviceSize,
382 draw_count: u32,
383 stride: u32,
384 ) -> Result<&mut Self> {
385 Ok(unsafe { self.draw_indexed_indirect_unchecked(buffer, offset, draw_count, stride) })
386 }
387
388 pub unsafe fn draw_indexed_indirect_unchecked(
389 &mut self,
390 buffer: Id<Buffer>,
391 offset: DeviceSize,
392 draw_count: u32,
393 stride: u32,
394 ) -> &mut Self {
395 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
396
397 let fns = self.device().fns();
398 unsafe {
399 (fns.v1_0.cmd_draw_indexed_indirect)(
400 self.handle(),
401 buffer.handle(),
402 offset,
403 draw_count,
404 stride,
405 )
406 };
407
408 self
409 }
410
411 /// Performs multiple draw operations using a primitive shading graphics pipeline, using an
412 /// index buffer, and reading the number of draw operations from a separate buffer.
413 ///
414 /// One draw is performed for each [`DrawIndexedIndirectCommand`] struct that is read from
415 /// `buffer` starting at `offset`, with the offset increasing by `stride` bytes for each
416 /// successive draw. The number of draws to perform is read from `count_buffer` at
417 /// `count_buffer_offset`, or specified by `max_draw_count`, whichever is lower. This number is
418 /// limited by the [`max_draw_indirect_count`] limit.
419 ///
420 /// An index buffer must have been bound using [`bind_index_buffer`], and the index ranges of
421 /// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound
422 /// index buffer.
423 ///
424 /// A primitive shading graphics pipeline must have been bound using
425 /// [`bind_pipeline_graphics`]. Any resources used by the graphics pipeline, such as descriptor
426 /// sets, vertex buffers and dynamic state, must have been set beforehand. If the bound
427 /// graphics pipeline uses vertex buffers, then the instance ranges of each
428 /// `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound vertex
429 /// buffers.
430 ///
431 /// # Safety
432 ///
433 /// - The general [shader safety requirements] apply.
434 /// - The [safety requirements for `DrawIndexedIndirectCommand`] apply.
435 /// - The count stored in `count_buffer` must not be greater than the
436 /// [`max_draw_indirect_count`] device limit.
437 /// - The count stored in `count_buffer` must fall within the range of `buffer`.
438 ///
439 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
440 /// [`bind_index_buffer`]: Self::bind_index_buffer
441 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
442 /// [shader safety requirements]: vulkano::shader#safety
443 /// [safety requirements for `DrawIndexedIndirectCommand`]: DrawIndexedIndirectCommand#safety
444 pub unsafe fn draw_indexed_indirect_count(
445 &mut self,
446 buffer: Id<Buffer>,
447 offset: DeviceSize,
448 count_buffer: Id<Buffer>,
449 count_buffer_offset: DeviceSize,
450 max_draw_count: u32,
451 stride: u32,
452 ) -> Result<&mut Self> {
453 Ok(unsafe {
454 self.draw_indexed_indirect_count_unchecked(
455 buffer,
456 offset,
457 count_buffer,
458 count_buffer_offset,
459 max_draw_count,
460 stride,
461 )
462 })
463 }
464
465 pub unsafe fn draw_indexed_indirect_count_unchecked(
466 &mut self,
467 buffer: Id<Buffer>,
468 offset: DeviceSize,
469 count_buffer: Id<Buffer>,
470 count_buffer_offset: DeviceSize,
471 max_draw_count: u32,
472 stride: u32,
473 ) -> &mut Self {
474 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
475 let count_buffer = unsafe { self.accesses.buffer_unchecked(count_buffer) };
476
477 let device = self.device();
478 let fns = device.fns();
479 let cmd_draw_indexed_indirect_count = if device.api_version() >= Version::V1_2 {
480 fns.v1_2.cmd_draw_indexed_indirect_count
481 } else if device.enabled_extensions().khr_draw_indirect_count {
482 fns.khr_draw_indirect_count
483 .cmd_draw_indexed_indirect_count_khr
484 } else if device.enabled_extensions().amd_draw_indirect_count {
485 fns.amd_draw_indirect_count
486 .cmd_draw_indexed_indirect_count_amd
487 } else {
488 std::process::abort();
489 };
490
491 unsafe {
492 cmd_draw_indexed_indirect_count(
493 self.handle(),
494 buffer.handle(),
495 offset,
496 count_buffer.handle(),
497 count_buffer_offset,
498 max_draw_count,
499 stride,
500 )
501 };
502
503 self
504 }
505
506 /// Perform a single draw operation using a mesh shading graphics pipeline.
507 ///
508 /// A mesh shading graphics pipeline must have been bound using [`bind_pipeline_graphics`]. Any
509 /// resources used by the graphics pipeline, such as descriptor sets and dynamic state, must
510 /// have been set beforehand.
511 ///
512 /// # Safety
513 ///
514 /// - The general [shader safety requirements] apply.
515 ///
516 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
517 /// [shader safety requirements]: vulkano::shader#safety
518 pub unsafe fn draw_mesh_tasks(&mut self, group_counts: [u32; 3]) -> Result<&mut Self> {
519 Ok(unsafe { self.draw_mesh_tasks_unchecked(group_counts) })
520 }
521
522 pub unsafe fn draw_mesh_tasks_unchecked(&mut self, group_counts: [u32; 3]) -> &mut Self {
523 let fns = self.device().fns();
524 unsafe {
525 (fns.ext_mesh_shader.cmd_draw_mesh_tasks_ext)(
526 self.handle(),
527 group_counts[0],
528 group_counts[1],
529 group_counts[2],
530 )
531 };
532
533 self
534 }
535
536 /// Perform multiple draw operations using a mesh shading graphics pipeline.
537 ///
538 /// One draw is performed for each [`DrawMeshTasksIndirectCommand`] struct that is read from
539 /// `buffer` starting at `offset`, with the offset increasing by `stride` bytes for each
540 /// successive draw. `draw_count` draw commands are performed. The maximum number of draw
541 /// commands in the buffer is limited by the [`max_draw_indirect_count`] limit. This limit is 1
542 /// unless the [`multi_draw_indirect`] feature has been enabled.
543 ///
544 /// A mesh shading graphics pipeline must have been bound using [`bind_pipeline_graphics`]. Any
545 /// resources used by the graphics pipeline, such as descriptor sets and dynamic state, must
546 /// have been set beforehand.
547 ///
548 /// # Safety
549 ///
550 /// - The general [shader safety requirements] apply.
551 /// - The [safety requirements for `DrawMeshTasksIndirectCommand`] apply.
552 ///
553 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
554 /// [`multi_draw_indirect`]: vulkano::device::DeviceFeatures::multi_draw_indirect
555 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
556 /// [shader safety requirements]: vulkano::shader#safety
557 /// [safety requirements for `DrawMeshTasksIndirectCommand`]: DrawMeshTasksIndirectCommand#safety
558 pub unsafe fn draw_mesh_tasks_indirect(
559 &mut self,
560 buffer: Id<Buffer>,
561 offset: DeviceSize,
562 draw_count: u32,
563 stride: u32,
564 ) -> Result<&mut Self> {
565 Ok(unsafe { self.draw_mesh_tasks_indirect_unchecked(buffer, offset, draw_count, stride) })
566 }
567
568 pub unsafe fn draw_mesh_tasks_indirect_unchecked(
569 &mut self,
570 buffer: Id<Buffer>,
571 offset: DeviceSize,
572 draw_count: u32,
573 stride: u32,
574 ) -> &mut Self {
575 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
576
577 let fns = self.device().fns();
578 unsafe {
579 (fns.ext_mesh_shader.cmd_draw_mesh_tasks_indirect_ext)(
580 self.handle(),
581 buffer.handle(),
582 offset,
583 draw_count,
584 stride,
585 )
586 };
587
588 self
589 }
590
591 /// Performs multiple draw operations using a mesh shading graphics pipeline, reading the
592 /// number of draw operations from a separate buffer.
593 ///
594 /// One draw is performed for each [`DrawMeshTasksIndirectCommand`] struct that is read from
595 /// `buffer` starting at `offset`, with the offset increasing by `stride` bytes after each
596 /// successive draw. The number of draws to perform is read from `count_buffer`, or specified
597 /// by `max_draw_count`, whichever is lower. This number is limited by the
598 /// [`max_draw_indirect_count`] limit.
599 ///
600 /// A mesh shading graphics pipeline must have been bound using [`bind_pipeline_graphics`]. Any
601 /// resources used by the graphics pipeline, such as descriptor sets and dynamic state, must
602 /// have been set beforehand.
603 ///
604 /// # Safety
605 ///
606 /// - The general [shader safety requirements] apply.
607 /// - The [safety requirements for `DrawMeshTasksIndirectCommand`] apply.
608 /// - The count stored in `count_buffer` must not be greater than the
609 /// [`max_draw_indirect_count`] device limit.
610 /// - The count stored in `count_buffer` must fall within the range of `buffer`.
611 ///
612 /// [`max_draw_indirect_count`]: vulkano::device::DeviceProperties::max_draw_indirect_count
613 /// [`bind_pipeline_graphics`]: Self::bind_pipeline_graphics
614 /// [shader safety requirements]: vulkano::shader#safety
615 /// [safety requirements for `DrawMeshTasksIndirectCommand`]: DrawMeshTasksIndirectCommand#safety
616 pub unsafe fn draw_mesh_tasks_indirect_count(
617 &mut self,
618 buffer: Id<Buffer>,
619 offset: DeviceSize,
620 count_buffer: Id<Buffer>,
621 count_buffer_offset: DeviceSize,
622 max_draw_count: u32,
623 stride: u32,
624 ) -> Result<&mut Self> {
625 Ok(unsafe {
626 self.draw_mesh_tasks_indirect_count_unchecked(
627 buffer,
628 offset,
629 count_buffer,
630 count_buffer_offset,
631 max_draw_count,
632 stride,
633 )
634 })
635 }
636
637 pub unsafe fn draw_mesh_tasks_indirect_count_unchecked(
638 &mut self,
639 buffer: Id<Buffer>,
640 offset: DeviceSize,
641 count_buffer: Id<Buffer>,
642 count_buffer_offset: DeviceSize,
643 max_draw_count: u32,
644 stride: u32,
645 ) -> &mut Self {
646 let buffer = unsafe { self.accesses.buffer_unchecked(buffer) };
647 let count_buffer = unsafe { self.accesses.buffer_unchecked(count_buffer) };
648
649 let fns = self.device().fns();
650 unsafe {
651 (fns.ext_mesh_shader.cmd_draw_mesh_tasks_indirect_count_ext)(
652 self.handle(),
653 buffer.handle(),
654 offset,
655 count_buffer.handle(),
656 count_buffer_offset,
657 max_draw_count,
658 stride,
659 )
660 };
661
662 self
663 }
664
665 /// Performs a single ray tracing operation using a ray tracing pipeline.
666 ///
667 /// A ray tracing pipeline must have been bound using [`bind_pipeline_ray_tracing`]. Any
668 /// resources used by the ray tracing pipeline, such as descriptor sets, must have been set
669 /// beforehand.
670 ///
671 /// # Safety
672 ///
673 /// - The general [shader safety requirements] apply.
674 ///
675 /// [`bind_pipeline_ray_tracing`]: Self::bind_pipeline_ray_tracing
676 /// [shader safety requirements]: vulkano::shader#safety
677 pub unsafe fn trace_rays(
678 &mut self,
679 shader_binding_table_addresses: &ShaderBindingTableAddresses,
680 dimensions: [u32; 3],
681 ) -> Result<&mut Self> {
682 Ok(unsafe { self.trace_rays_unchecked(shader_binding_table_addresses, dimensions) })
683 }
684
685 pub unsafe fn trace_rays_unchecked(
686 &mut self,
687 shader_binding_table_addresses: &ShaderBindingTableAddresses,
688 dimensions: [u32; 3],
689 ) -> &mut Self {
690 let raygen = shader_binding_table_addresses.raygen.to_vk();
691 let miss = shader_binding_table_addresses.miss.to_vk();
692 let hit = shader_binding_table_addresses.hit.to_vk();
693 let callable = shader_binding_table_addresses.callable.to_vk();
694
695 let fns = self.device().fns();
696 unsafe {
697 (fns.khr_ray_tracing_pipeline.cmd_trace_rays_khr)(
698 self.handle(),
699 &raygen,
700 &miss,
701 &hit,
702 &callable,
703 dimensions[0],
704 dimensions[1],
705 dimensions[2],
706 )
707 };
708
709 self
710 }
711}