rendy_command/buffer/
submit.rs

1use {
2    super::{
3        level::PrimaryLevel,
4        state::{ExecutableState, InvalidState, PendingState},
5        usage::{MultiShot, NoSimultaneousUse, OneShot, OutsideRenderPass, SimultaneousUse},
6        CommandBuffer,
7    },
8    crate::family::FamilyId,
9};
10
11/// Structure contains command buffer ready for submission.
12#[derive(Debug)]
13pub struct Submit<
14    B: rendy_core::hal::Backend,
15    S = NoSimultaneousUse,
16    L = PrimaryLevel,
17    P = OutsideRenderPass,
18> {
19    raw: std::ptr::NonNull<B::CommandBuffer>,
20    family: FamilyId,
21    simultaneous: S,
22    level: L,
23    pass_continue: P,
24}
25
26unsafe impl<B, S, L, P> Send for Submit<B, S, L, P>
27where
28    B: rendy_core::hal::Backend,
29    B::CommandBuffer: Send + Sync,
30    FamilyId: Send,
31    S: Send,
32    L: Send,
33    P: Send,
34{
35}
36
37unsafe impl<B, S, L, P> Sync for Submit<B, S, L, P>
38where
39    B: rendy_core::hal::Backend,
40    B::CommandBuffer: Send + Sync,
41    S: Sync,
42    L: Sync,
43    P: Sync,
44{
45}
46
47/// Submittable object.
48/// Values that implement this trait can be submitted to the queues
49/// or executed as part of primary buffers (in case of `Submittable<B, SecondaryLevel>`).
50pub unsafe trait Submittable<B: rendy_core::hal::Backend, L = PrimaryLevel, P = OutsideRenderPass> {
51    /// Get family that this submittable is belong to.
52    fn family(&self) -> FamilyId;
53
54    /// Get raw command buffer.
55    /// This function is intended for submitting command buffer into raw queue.
56    ///
57    /// # Safety
58    ///
59    /// This function returns unbound reference to the raw command buffer.
60    /// The actual lifetime of the command buffer is tied to the original `CommandBuffer` wrapper.
61    /// `CommandBuffer` must not destroy raw command buffer or give access to it before submitted command is complete so
62    /// using this funcion to submit command buffer into queue must be valid.
63    unsafe fn raw<'a>(self) -> &'a B::CommandBuffer;
64}
65
66unsafe impl<B, S, L, P> Submittable<B, L, P> for Submit<B, S, L, P>
67where
68    B: rendy_core::hal::Backend,
69{
70    fn family(&self) -> FamilyId {
71        self.family
72    }
73
74    unsafe fn raw<'a>(self) -> &'a B::CommandBuffer {
75        &*self.raw.as_ptr()
76    }
77}
78
79unsafe impl<'a, B, L, P> Submittable<B, L, P> for &'a Submit<B, SimultaneousUse, L, P>
80where
81    B: rendy_core::hal::Backend,
82{
83    fn family(&self) -> FamilyId {
84        self.family
85    }
86
87    unsafe fn raw<'b>(self) -> &'b B::CommandBuffer {
88        &*self.raw.as_ptr()
89    }
90}
91
92impl<B, C, P, L, R> CommandBuffer<B, C, ExecutableState<OneShot, P>, L, R>
93where
94    B: rendy_core::hal::Backend,
95    P: Copy,
96    L: Copy,
97{
98    /// Produce `Submit` object that can be used to populate submission.
99    pub fn submit_once(
100        self,
101    ) -> (
102        Submit<B, NoSimultaneousUse, L, P>,
103        CommandBuffer<B, C, PendingState<InvalidState>, L, R>,
104    ) {
105        let pass_continue = self.state.1;
106        let level = self.level;
107
108        let buffer = unsafe { self.change_state(|_| PendingState(InvalidState)) };
109
110        let submit = Submit {
111            raw: buffer.raw,
112            family: buffer.family,
113            pass_continue,
114            simultaneous: NoSimultaneousUse,
115            level,
116        };
117
118        (submit, buffer)
119    }
120}
121
122impl<B, C, S, L, P, R> CommandBuffer<B, C, ExecutableState<MultiShot<S>, P>, L, R>
123where
124    B: rendy_core::hal::Backend,
125    P: Copy,
126    S: Copy,
127    L: Copy,
128{
129    /// Produce `Submit` object that can be used to populate submission.
130    pub fn submit(
131        self,
132    ) -> (
133        Submit<B, S, L, P>,
134        CommandBuffer<B, C, PendingState<ExecutableState<MultiShot<S>, P>>, L, R>,
135    ) {
136        let MultiShot(simultaneous) = self.state.0;
137        let pass_continue = self.state.1;
138        let level = self.level;
139
140        let buffer = unsafe { self.change_state(|state| PendingState(state)) };
141
142        let submit = Submit {
143            raw: buffer.raw,
144            family: buffer.family,
145            pass_continue,
146            simultaneous,
147            level,
148        };
149
150        (submit, buffer)
151    }
152}