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}