rendy_command/buffer/
encoder.rs

1use {
2    super::{
3        level::{Level, PrimaryLevel, SecondaryLevel},
4        state::RecordingState,
5        submit::Submittable,
6        usage::RenderPassContinue,
7        CommandBuffer,
8    },
9    crate::{
10        capability::{Capability, Compute, Graphics, Supports, Transfer},
11        family::FamilyId,
12    },
13};
14
15/// Draw command for [`draw_indirect`].
16///
17/// [`draw_indirect`]: ../struct.RenderPassEncoder.html#method.draw_indirect
18#[repr(C)]
19#[derive(Clone, Copy, Debug)]
20pub struct DrawCommand {
21    /// Number of vertices to draw.
22    pub vertex_count: u32,
23
24    /// Number of instanced to draw.
25    pub instance_count: u32,
26
27    /// First vertex index.
28    pub first_vertex: u32,
29
30    /// First instance index.
31    pub first_instance: u32,
32}
33
34/// Draw command for [`draw_indexed_indirect`].
35///
36/// [`draw_indexed_indirect`]: ../struct.RenderPassEncoder.html#method.draw_indexed_indirect
37#[repr(C)]
38#[derive(Clone, Copy, Debug)]
39pub struct DrawIndexedCommand {
40    /// Number of indices to draw.
41    pub index_count: u32,
42
43    /// Number of instances to draw.
44    pub instance_count: u32,
45
46    /// First index.
47    pub first_index: u32,
48
49    /// Vertex offset that is added to index before indexing the vertex buffer.
50    pub vertex_offset: i32,
51
52    /// First instance index.
53    pub first_instance: u32,
54}
55
56/// Draw command for dispatch.
57#[repr(C)]
58#[derive(Clone, Copy, Debug)]
59pub struct DispatchCommand {
60    /// Number of local workgroups to dispatch in the X dimension.
61    pub x: u32,
62
63    /// Number of local workgroups to dispatch in the Y dimension.
64    pub y: u32,
65
66    /// Number of local workgroups to dispatch in the Z dimension.
67    pub z: u32,
68}
69
70/// Encoder for recording commands inside or outside renderpass.
71#[derive(Debug)]
72pub struct EncoderCommon<'a, B: rendy_core::hal::Backend, C> {
73    raw: &'a mut B::CommandBuffer,
74    capability: C,
75    family: FamilyId,
76}
77
78impl<'a, B, C> EncoderCommon<'a, B, C>
79where
80    B: rendy_core::hal::Backend,
81{
82    /// Bind index buffer.
83    /// Last bound index buffer is used in [`draw_indexed`] command.
84    ///
85    /// Note that `draw*` commands available only inside renderpass.
86    ///
87    /// [`draw_indexed`]: ../struct.RenderPassEncoder.html#method.draw_indexed
88    ///
89    /// # Safety
90    ///
91    /// `offset` must not be greater than the size of `buffer`.
92    /// Sum of `offset` and starting address of the `buffer` must be
93    /// multiple of index size indicated by `index_type`.
94    ///
95    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindIndexBuffer.html
96    pub unsafe fn bind_index_buffer<'b>(
97        &mut self,
98        buffer: &'b B::Buffer,
99        offset: u64,
100        index_type: rendy_core::hal::IndexType,
101    ) where
102        C: Supports<Graphics>,
103    {
104        self.capability.assert();
105        rendy_core::hal::command::CommandBuffer::bind_index_buffer(
106            self.raw,
107            rendy_core::hal::buffer::IndexBufferView {
108                buffer: buffer,
109                offset,
110                index_type,
111            },
112        )
113    }
114
115    /// Bind vertex buffers.
116    /// Last bound vertex buffer is used in [`draw`] and [`draw_indexed`] commands.
117    ///
118    /// Note that `draw*` commands available only inside renderpass.
119    ///
120    /// [`draw`]: ../struct.RenderPassEncoder.html#method.draw
121    /// [`draw_indexed`]: ../struct.RenderPassEncoder.html#method.draw_indexed
122    ///
123    /// # Safety
124    ///
125    /// `first_binding + buffers.into_iter().count()` must less than or equal to the `maxVertexInputBindings`
126    /// device limit.
127    ///
128    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindVertexBuffers.html
129    pub unsafe fn bind_vertex_buffers<'b>(
130        &mut self,
131        first_binding: u32,
132        buffers: impl IntoIterator<Item = (&'b B::Buffer, u64)>,
133    ) where
134        C: Supports<Graphics>,
135    {
136        self.capability.assert();
137        rendy_core::hal::command::CommandBuffer::bind_vertex_buffers(
138            self.raw,
139            first_binding,
140            buffers,
141        )
142    }
143
144    /// Bind graphics pipeline.
145    ///
146    /// Last bound vertex buffer is used in [`draw`], [`draw_indexed`], [`draw_indirect`] and [`draw_indexed_indirect`] commands.
147    ///
148    /// [`draw_indexed_indirect`]: ../struct.RenderPassEncoder.html#method.draw_indexed_indirect
149    /// [`draw_indirect`]: ../struct.RenderPassEncoder.html#method.draw_indirect
150    pub fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline)
151    where
152        C: Supports<Graphics>,
153    {
154        self.capability.assert();
155
156        unsafe {
157            rendy_core::hal::command::CommandBuffer::bind_graphics_pipeline(self.raw, pipeline);
158        }
159    }
160
161    /// Bind descriptor sets to graphics pipeline.
162    ///
163    /// # Safety
164    ///
165    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindDescriptorSets.html
166    pub unsafe fn bind_graphics_descriptor_sets<'b>(
167        &mut self,
168        layout: &B::PipelineLayout,
169        first_set: u32,
170        sets: impl IntoIterator<Item = &'b B::DescriptorSet>,
171        offsets: impl IntoIterator<Item = u32>,
172    ) where
173        C: Supports<Graphics>,
174    {
175        self.capability.assert();
176
177        rendy_core::hal::command::CommandBuffer::bind_graphics_descriptor_sets(
178            self.raw,
179            layout,
180            first_set as _,
181            sets,
182            offsets,
183        );
184    }
185
186    /// Bind compute pipeline.
187    pub fn bind_compute_pipeline(&mut self, pipeline: &B::ComputePipeline)
188    where
189        C: Supports<Compute>,
190    {
191        self.capability.assert();
192
193        unsafe {
194            rendy_core::hal::command::CommandBuffer::bind_compute_pipeline(self.raw, pipeline);
195        }
196    }
197
198    /// Bind descriptor sets to compute pipeline.
199    ///
200    /// # Safety
201    ///
202    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBindDescriptorSets.html
203    pub unsafe fn bind_compute_descriptor_sets<'b>(
204        &mut self,
205        layout: &B::PipelineLayout,
206        first_set: u32,
207        sets: impl IntoIterator<Item = &'b B::DescriptorSet>,
208        offsets: impl IntoIterator<Item = u32>,
209    ) where
210        C: Supports<Compute>,
211    {
212        self.capability.assert();
213
214        rendy_core::hal::command::CommandBuffer::bind_compute_descriptor_sets(
215            self.raw,
216            layout,
217            first_set as usize,
218            sets,
219            offsets,
220        );
221    }
222
223    /// Insert pipeline barrier.
224    ///
225    /// # Safety
226    ///
227    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdPipelineBarrier.html
228    pub unsafe fn pipeline_barrier<'b>(
229        &mut self,
230        stages: std::ops::Range<rendy_core::hal::pso::PipelineStage>,
231        dependencies: rendy_core::hal::memory::Dependencies,
232        barriers: impl IntoIterator<Item = rendy_core::hal::memory::Barrier<'b, B>>,
233    ) {
234        rendy_core::hal::command::CommandBuffer::pipeline_barrier(
235            self.raw,
236            stages,
237            dependencies,
238            barriers,
239        )
240    }
241
242    /// Push graphics constants.
243    ///
244    /// # Safety
245    ///
246    /// `offset` must be multiple of 4.
247    /// `constants.len() + offset`, must be less than or equal to the
248    /// `maxPushConstantsSize` device limit.
249    ///
250    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdPushConstants.html
251    pub unsafe fn push_constants<'b>(
252        &mut self,
253        layout: &B::PipelineLayout,
254        stages: rendy_core::hal::pso::ShaderStageFlags,
255        offset: u32,
256        constants: &[u32],
257    ) {
258        rendy_core::hal::command::CommandBuffer::push_graphics_constants(
259            self.raw, layout, stages, offset, constants,
260        );
261    }
262
263    /// Set viewports
264    ///
265    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetViewport.html
266    pub unsafe fn set_viewports<'b>(
267        &mut self,
268        first_viewport: u32,
269        viewports: impl IntoIterator<Item = &'b rendy_core::hal::pso::Viewport>,
270    ) where
271        C: Supports<Graphics>,
272    {
273        self.capability.assert();
274        rendy_core::hal::command::CommandBuffer::set_viewports(self.raw, first_viewport, viewports)
275    }
276
277    /// Set scissors
278    ///
279    /// # Safety
280    ///
281    /// `first_scissor + rects.count()` must be less than the
282    /// `maxViewports` device limit.
283    ///
284    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetScissor.html
285    pub unsafe fn set_scissors<'b>(
286        &mut self,
287        first_scissor: u32,
288        rects: impl IntoIterator<Item = &'b rendy_core::hal::pso::Rect>,
289    ) where
290        C: Supports<Graphics>,
291    {
292        self.capability.assert();
293        rendy_core::hal::command::CommandBuffer::set_scissors(self.raw, first_scissor, rects)
294    }
295
296    /// Set the stencil reference dynamic state
297    ///
298    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetStencilReference.html
299    pub unsafe fn set_stencil_reference(
300        &mut self,
301        faces: rendy_core::hal::pso::Face,
302        value: rendy_core::hal::pso::StencilValue,
303    ) where
304        C: Supports<Graphics>,
305    {
306        self.capability.assert();
307        rendy_core::hal::command::CommandBuffer::set_stencil_reference(self.raw, faces, value);
308    }
309
310    /// Set the stencil compare mask dynamic state
311    ///
312    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetStencilCompareMask.html
313    pub unsafe fn set_stencil_read_mask(
314        &mut self,
315        faces: rendy_core::hal::pso::Face,
316        value: rendy_core::hal::pso::StencilValue,
317    ) where
318        C: Supports<Graphics>,
319    {
320        self.capability.assert();
321        rendy_core::hal::command::CommandBuffer::set_stencil_read_mask(self.raw, faces, value);
322    }
323
324    /// Set the stencil write mask dynamic state
325    ///
326    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetStencilWriteMask.html
327    pub unsafe fn set_stencil_write_mask(
328        &mut self,
329        faces: rendy_core::hal::pso::Face,
330        value: rendy_core::hal::pso::StencilValue,
331    ) where
332        C: Supports<Graphics>,
333    {
334        self.capability.assert();
335        rendy_core::hal::command::CommandBuffer::set_stencil_write_mask(self.raw, faces, value);
336    }
337
338    /// Set the values of blend constants
339    ///
340    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetBlendConstants.html
341    pub unsafe fn set_blend_constants(&mut self, color: rendy_core::hal::pso::ColorValue)
342    where
343        C: Supports<Graphics>,
344    {
345        self.capability.assert();
346        rendy_core::hal::command::CommandBuffer::set_blend_constants(self.raw, color);
347    }
348
349    /// Set the depth bounds test values
350    ///
351    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetDepthBounds.html
352    pub unsafe fn set_depth_bounds(&mut self, bounds: std::ops::Range<f32>)
353    where
354        C: Supports<Graphics>,
355    {
356        self.capability.assert();
357        rendy_core::hal::command::CommandBuffer::set_depth_bounds(self.raw, bounds);
358    }
359
360    /// Set the dynamic line width state
361    ///
362    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetLineWidth.html
363    pub unsafe fn set_line_width(&mut self, width: f32)
364    where
365        C: Supports<Graphics>,
366    {
367        self.capability.assert();
368        rendy_core::hal::command::CommandBuffer::set_line_width(self.raw, width);
369    }
370
371    /// Set the depth bias dynamic state
372    ///
373    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdSetDepthBias.html
374    pub unsafe fn set_depth_bias(&mut self, depth_bias: rendy_core::hal::pso::DepthBias)
375    where
376        C: Supports<Graphics>,
377    {
378        self.capability.assert();
379        rendy_core::hal::command::CommandBuffer::set_depth_bias(self.raw, depth_bias);
380    }
381
382    /// Reborrow encoder.
383    pub fn reborrow<K>(&mut self) -> EncoderCommon<'_, B, K>
384    where
385        C: Supports<K>,
386    {
387        EncoderCommon {
388            capability: self.capability.supports().unwrap(),
389            raw: &mut *self.raw,
390            family: self.family,
391        }
392    }
393}
394
395/// Special encoder to record render-pass commands.
396#[derive(Debug)]
397pub struct RenderPassEncoder<'a, B: rendy_core::hal::Backend> {
398    inner: EncoderCommon<'a, B, Graphics>,
399}
400
401impl<'a, B> std::ops::Deref for RenderPassEncoder<'a, B>
402where
403    B: rendy_core::hal::Backend,
404{
405    type Target = EncoderCommon<'a, B, Graphics>;
406
407    fn deref(&self) -> &EncoderCommon<'a, B, Graphics> {
408        &self.inner
409    }
410}
411
412impl<'a, B> std::ops::DerefMut for RenderPassEncoder<'a, B>
413where
414    B: rendy_core::hal::Backend,
415{
416    fn deref_mut(&mut self) -> &mut EncoderCommon<'a, B, Graphics> {
417        &mut self.inner
418    }
419}
420
421impl<'a, B> RenderPassEncoder<'a, B>
422where
423    B: rendy_core::hal::Backend,
424{
425    /// Clear regions within bound framebuffer attachments
426    ///
427    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdClearAttachments.html#vkCmdBeginRenderPass
428    pub unsafe fn clear_attachments(
429        &mut self,
430        clears: impl IntoIterator<
431            Item = impl std::borrow::Borrow<rendy_core::hal::command::AttachmentClear>,
432        >,
433        rects: impl IntoIterator<Item = impl std::borrow::Borrow<rendy_core::hal::pso::ClearRect>>,
434    ) {
435        rendy_core::hal::command::CommandBuffer::clear_attachments(self.inner.raw, clears, rects);
436    }
437
438    /// Draw.
439    ///
440    /// # Safety
441    ///
442    /// The range of `vertices` must not exceed the size of the currently bound vertex buffer,
443    /// and the range of `instances` must not exceed the size of the currently bound instance
444    /// buffer.
445    ///
446    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDraw.html
447    pub unsafe fn draw(&mut self, vertices: std::ops::Range<u32>, instances: std::ops::Range<u32>) {
448        rendy_core::hal::command::CommandBuffer::draw(self.inner.raw, vertices, instances)
449    }
450
451    /// Draw indexed, with `base_vertex` specifying an offset that is treated as
452    /// vertex number 0.
453    ///
454    /// # Safety
455    ///
456    /// Same as `draw()`, plus the value of `base_vertex`.  So, `base_vertex + indices.end`
457    /// must not be larger than the currently bound vertex buffer.
458    ///
459    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDrawIndexed.html
460    pub unsafe fn draw_indexed(
461        &mut self,
462        indices: std::ops::Range<u32>,
463        base_vertex: i32,
464        instances: std::ops::Range<u32>,
465    ) {
466        rendy_core::hal::command::CommandBuffer::draw_indexed(
467            self.inner.raw,
468            indices,
469            base_vertex,
470            instances,
471        )
472    }
473
474    /// Draw indirect.
475    /// Similar to [`draw`] except takes vertices and instance data from `buffer` at specified `offset`.
476    /// `buffer` must contain `draw_count` of [`DrawCommand`] starting from `offset` with `stride` bytes between each.
477    ///
478    /// [`draw`]: trait.RenderPassInlineEncoder.html#tymethod.draw
479    /// [`DrawCommand`]: struct.DrawCommand.html
480    ///
481    /// # Safety
482    ///
483    /// Similar to `draw()`.
484    ///
485    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDrawIndirect.html
486    pub unsafe fn draw_indirect(
487        &mut self,
488        buffer: &B::Buffer,
489        offset: u64,
490        draw_count: u32,
491        stride: u32,
492    ) {
493        rendy_core::hal::command::CommandBuffer::draw_indirect(
494            self.inner.raw,
495            buffer,
496            offset,
497            draw_count,
498            stride,
499        )
500    }
501
502    /// Draw indirect with indices.
503    /// Similar to [`draw_indexed`] except takes vertices, indices and instance data from `buffer` at specified `offset`.
504    /// `buffer` must contain `draw_count` of [`DrawIndexedCommand`] starting from `offset` with `stride` bytes between each.
505    ///
506    /// [`draw`]: trait.RenderPassInlineEncoder.html#tymethod.draw_indexed
507    /// [`DrawIndexedCommand`]: struct.DrawIndexedCommand.html
508    ///
509    /// # Safety
510    ///
511    /// Similar to `draw_indexed()`
512    ///
513    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDrawIndexedIndirect.html
514    pub unsafe fn draw_indexed_indirect(
515        &mut self,
516        buffer: &B::Buffer,
517        offset: u64,
518        draw_count: u32,
519        stride: u32,
520    ) {
521        rendy_core::hal::command::CommandBuffer::draw_indexed_indirect(
522            self.inner.raw,
523            buffer,
524            offset,
525            draw_count,
526            stride,
527        )
528    }
529
530    /// Reborrow encoder.
531    pub fn reborrow(&mut self) -> RenderPassEncoder<'_, B> {
532        RenderPassEncoder {
533            inner: self.inner.reborrow(),
534        }
535    }
536}
537
538/// Special encoder to record commands inside render pass.
539#[derive(Debug)]
540pub struct RenderPassInlineEncoder<'a, B: rendy_core::hal::Backend> {
541    inner: RenderPassEncoder<'a, B>,
542}
543
544impl<'a, B> Drop for RenderPassInlineEncoder<'a, B>
545where
546    B: rendy_core::hal::Backend,
547{
548    fn drop(&mut self) {
549        unsafe { rendy_core::hal::command::CommandBuffer::end_render_pass(self.inner.inner.raw) }
550    }
551}
552
553impl<'a, B> std::ops::Deref for RenderPassInlineEncoder<'a, B>
554where
555    B: rendy_core::hal::Backend,
556{
557    type Target = RenderPassEncoder<'a, B>;
558
559    fn deref(&self) -> &RenderPassEncoder<'a, B> {
560        &self.inner
561    }
562}
563
564impl<'a, B> std::ops::DerefMut for RenderPassInlineEncoder<'a, B>
565where
566    B: rendy_core::hal::Backend,
567{
568    fn deref_mut(&mut self) -> &mut RenderPassEncoder<'a, B> {
569        &mut self.inner
570    }
571}
572
573impl<'a, B> RenderPassInlineEncoder<'a, B>
574where
575    B: rendy_core::hal::Backend,
576{
577    /// Record next subpass inline.
578    pub fn next_subpass_inline(self) -> RenderPassInlineEncoder<'a, B> {
579        unsafe {
580            rendy_core::hal::command::CommandBuffer::next_subpass(
581                self.inner.inner.raw,
582                rendy_core::hal::command::SubpassContents::Inline,
583            );
584        }
585
586        self
587    }
588
589    /// Record next subpass secondary.
590    pub fn next_subpass_secondary(self) -> RenderPassSecondaryEncoder<'a, B> {
591        unsafe {
592            rendy_core::hal::command::CommandBuffer::next_subpass(
593                self.inner.inner.raw,
594                rendy_core::hal::command::SubpassContents::SecondaryBuffers,
595            );
596        }
597
598        unsafe {
599            let next = RenderPassSecondaryEncoder {
600                inner: std::ptr::read(&self.inner.inner),
601            };
602
603            std::mem::forget(self);
604            next
605        }
606    }
607}
608
609/// Special encoder to execute secondary buffers inside render pass.
610#[derive(Debug)]
611pub struct RenderPassSecondaryEncoder<'a, B: rendy_core::hal::Backend> {
612    inner: EncoderCommon<'a, B, Graphics>,
613}
614
615impl<'a, B> Drop for RenderPassSecondaryEncoder<'a, B>
616where
617    B: rendy_core::hal::Backend,
618{
619    fn drop(&mut self) {
620        unsafe { rendy_core::hal::command::CommandBuffer::end_render_pass(self.inner.raw) }
621    }
622}
623
624impl<'a, B> RenderPassSecondaryEncoder<'a, B>
625where
626    B: rendy_core::hal::Backend,
627{
628    /// Execute commands from secondary buffers.
629    pub fn execute_commands(
630        &mut self,
631        submittables: impl IntoIterator<Item = impl Submittable<B, SecondaryLevel, RenderPassContinue>>,
632    ) {
633        let family = self.inner.family;
634        unsafe {
635            rendy_core::hal::command::CommandBuffer::execute_commands(
636                self.inner.raw,
637                submittables.into_iter().map(|submit| {
638                    assert_eq!(family, submit.family());
639                    submit.raw()
640                }),
641            )
642        }
643    }
644
645    /// Record next subpass inline.
646    pub fn next_subpass_inline(self) -> RenderPassInlineEncoder<'a, B> {
647        unsafe {
648            rendy_core::hal::command::CommandBuffer::next_subpass(
649                self.inner.raw,
650                rendy_core::hal::command::SubpassContents::Inline,
651            );
652
653            let next = RenderPassInlineEncoder {
654                inner: RenderPassEncoder {
655                    inner: std::ptr::read(&self.inner),
656                },
657            };
658
659            std::mem::forget(self);
660            next
661        }
662    }
663
664    /// Record next subpass secondary.
665    pub fn next_subpass_secondary(self) -> RenderPassSecondaryEncoder<'a, B> {
666        unsafe {
667            rendy_core::hal::command::CommandBuffer::next_subpass(
668                self.inner.raw,
669                rendy_core::hal::command::SubpassContents::SecondaryBuffers,
670            );
671        }
672
673        self
674    }
675}
676
677/// Trait to encode commands outside render pass.
678#[derive(Debug)]
679pub struct Encoder<'a, B: rendy_core::hal::Backend, C, L> {
680    inner: EncoderCommon<'a, B, C>,
681    level: L,
682}
683
684impl<'a, B, C, L> std::ops::Deref for Encoder<'a, B, C, L>
685where
686    B: rendy_core::hal::Backend,
687{
688    type Target = EncoderCommon<'a, B, C>;
689
690    fn deref(&self) -> &EncoderCommon<'a, B, C> {
691        &self.inner
692    }
693}
694
695impl<'a, B, C, L> std::ops::DerefMut for Encoder<'a, B, C, L>
696where
697    B: rendy_core::hal::Backend,
698{
699    fn deref_mut(&mut self) -> &mut EncoderCommon<'a, B, C> {
700        &mut self.inner
701    }
702}
703
704impl<'a, B, C> Encoder<'a, B, C, PrimaryLevel>
705where
706    B: rendy_core::hal::Backend,
707{
708    /// Beging recording render pass inline.
709    pub fn begin_render_pass_inline(
710        &mut self,
711        render_pass: &B::RenderPass,
712        framebuffer: &B::Framebuffer,
713        render_area: rendy_core::hal::pso::Rect,
714        clear_values: &[rendy_core::hal::command::ClearValue],
715    ) -> RenderPassInlineEncoder<'_, B>
716    where
717        C: Supports<Graphics>,
718    {
719        self.capability.assert();
720
721        unsafe {
722            rendy_core::hal::command::CommandBuffer::begin_render_pass(
723                self.inner.raw,
724                render_pass,
725                framebuffer,
726                render_area,
727                clear_values,
728                rendy_core::hal::command::SubpassContents::Inline,
729            )
730        }
731
732        RenderPassInlineEncoder {
733            inner: RenderPassEncoder {
734                inner: self.inner.reborrow(),
735            },
736        }
737    }
738
739    /// Beging recording render pass secondary.
740    pub fn begin_render_pass_secondary(
741        &mut self,
742        render_pass: &B::RenderPass,
743        framebuffer: &B::Framebuffer,
744        render_area: rendy_core::hal::pso::Rect,
745        clear_values: &[rendy_core::hal::command::ClearValue],
746    ) -> RenderPassSecondaryEncoder<'_, B>
747    where
748        C: Supports<Graphics>,
749    {
750        self.capability.assert();
751
752        unsafe {
753            rendy_core::hal::command::CommandBuffer::begin_render_pass(
754                self.inner.raw,
755                render_pass,
756                framebuffer,
757                render_area,
758                clear_values,
759                rendy_core::hal::command::SubpassContents::SecondaryBuffers,
760            )
761        }
762
763        RenderPassSecondaryEncoder {
764            inner: self.inner.reborrow(),
765        }
766    }
767
768    /// Execute commands from secondary buffers.
769    pub fn execute_commands(
770        &mut self,
771        submittables: impl IntoIterator<Item = impl Submittable<B, SecondaryLevel>>,
772    ) {
773        let family = self.inner.family;
774        unsafe {
775            rendy_core::hal::command::CommandBuffer::execute_commands(
776                self.inner.raw,
777                submittables.into_iter().map(|submit| {
778                    assert_eq!(family, submit.family());
779                    submit.raw()
780                }),
781            )
782        }
783    }
784}
785
786impl<'a, B, C, L> Encoder<'a, B, C, L>
787where
788    B: rendy_core::hal::Backend,
789{
790    /// Get encoder level.
791    pub fn level(&self) -> L
792    where
793        L: Level,
794    {
795        self.level
796    }
797
798    /// Copy buffer regions.
799    /// `src` and `dst` can be the same buffer or alias in memory.
800    /// But regions must not overlap.
801    /// Otherwise resulting values are undefined.
802    ///
803    /// # Safety
804    ///
805    /// The size of the copy region in any `regions` must not exceed the
806    /// length of the corresponding buffer.
807    ///
808    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyBuffer.html
809    pub unsafe fn copy_buffer(
810        &mut self,
811        src: &B::Buffer,
812        dst: &B::Buffer,
813        regions: impl IntoIterator<Item = rendy_core::hal::command::BufferCopy>,
814    ) where
815        C: Supports<Transfer>,
816    {
817        self.capability.assert();
818
819        rendy_core::hal::command::CommandBuffer::copy_buffer(self.inner.raw, src, dst, regions)
820    }
821
822    /// Copy buffer region to image subresource range.
823    ///
824    /// # Safety
825    ///
826    /// Same as `copy_buffer()`
827    ///
828    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyBufferToImage.html
829    pub unsafe fn copy_buffer_to_image(
830        &mut self,
831        src: &B::Buffer,
832        dst: &B::Image,
833        dst_layout: rendy_core::hal::image::Layout,
834        regions: impl IntoIterator<Item = rendy_core::hal::command::BufferImageCopy>,
835    ) where
836        C: Supports<Transfer>,
837    {
838        self.capability.assert();
839
840        rendy_core::hal::command::CommandBuffer::copy_buffer_to_image(
841            self.inner.raw,
842            src,
843            dst,
844            dst_layout,
845            regions,
846        )
847    }
848
849    /// Copy image regions.
850    ///
851    /// # Safety
852    ///
853    /// Same as `copy_buffer()`
854    ///
855    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdCopyImage.html
856    pub unsafe fn copy_image(
857        &mut self,
858        src: &B::Image,
859        src_layout: rendy_core::hal::image::Layout,
860        dst: &B::Image,
861        dst_layout: rendy_core::hal::image::Layout,
862        regions: impl IntoIterator<Item = rendy_core::hal::command::ImageCopy>,
863    ) where
864        C: Supports<Transfer>,
865    {
866        self.capability.assert();
867
868        rendy_core::hal::command::CommandBuffer::copy_image(
869            self.inner.raw,
870            src,
871            src_layout,
872            dst,
873            dst_layout,
874            regions,
875        )
876    }
877
878    /// Blit image regions, potentially using specified filter when resize is necessary.
879    ///
880    /// # Safety
881    ///
882    /// Same as `copy_buffer()`
883    ///
884    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdBlitImage.html
885    pub unsafe fn blit_image(
886        &mut self,
887        src: &B::Image,
888        src_layout: rendy_core::hal::image::Layout,
889        dst: &B::Image,
890        dst_layout: rendy_core::hal::image::Layout,
891        filter: rendy_core::hal::image::Filter,
892        regions: impl IntoIterator<Item = rendy_core::hal::command::ImageBlit>,
893    ) where
894        C: Supports<Graphics>,
895    {
896        self.capability.assert();
897
898        rendy_core::hal::command::CommandBuffer::blit_image(
899            self.inner.raw,
900            src,
901            src_layout,
902            dst,
903            dst_layout,
904            filter,
905            regions,
906        )
907    }
908
909    /// Dispatch compute.
910    ///
911    /// # Safety
912    ///
913    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDispatch.html
914    pub unsafe fn dispatch(&mut self, x: u32, y: u32, z: u32)
915    where
916        C: Supports<Compute>,
917    {
918        self.capability.assert();
919
920        rendy_core::hal::command::CommandBuffer::dispatch(self.inner.raw, [x, y, z])
921    }
922
923    /// Dispatch indirect.
924    /// Similar to [`dispatch`] except takes vertices and indices from `buffer` at specified `offset`.
925    /// `buffer` must contain [`DispatchCommand`] at `offset`.
926    ///
927    /// [`dispatch`]: trait.Encoder.html#tymethod.dispatch
928    /// [`DispatchCommand`]: struct.DispatchCommand.html
929    ///
930    /// # Safety
931    ///
932    /// See: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkCmdDispatchIndirect.html
933    pub unsafe fn dispatch_indirect(&mut self, buffer: &B::Buffer, offset: u64)
934    where
935        C: Supports<Compute>,
936    {
937        self.capability.assert();
938
939        rendy_core::hal::command::CommandBuffer::dispatch_indirect(self.inner.raw, buffer, offset)
940    }
941}
942
943impl<B, C, U, L, R> CommandBuffer<B, C, RecordingState<U>, L, R>
944where
945    B: rendy_core::hal::Backend,
946    C: Capability,
947    L: Level,
948{
949    /// Get encoder that will encode commands into this command buffer.
950    pub fn encoder(&mut self) -> Encoder<'_, B, C, L> {
951        Encoder {
952            level: self.level,
953            inner: EncoderCommon {
954                capability: self.capability,
955                family: self.family,
956                raw: self.raw(),
957            },
958        }
959    }
960}
961
962impl<B, C, U, R> CommandBuffer<B, C, RecordingState<U, RenderPassContinue>, SecondaryLevel, R>
963where
964    B: rendy_core::hal::Backend,
965    C: Supports<Graphics>,
966{
967    /// Get encoder that will encode render-pass commands into this command buffer.
968    pub fn render_pass_encoder(&mut self) -> RenderPassEncoder<'_, B> {
969        RenderPassEncoder {
970            inner: EncoderCommon {
971                capability: self.capability.supports().unwrap(),
972                family: self.family,
973                raw: self.raw(),
974            },
975        }
976    }
977}