rafx_api/
command_pool.rs

1#[cfg(feature = "rafx-dx12")]
2use crate::dx12::RafxCommandPoolDx12;
3#[cfg(any(
4    feature = "rafx-empty",
5    not(any(
6        feature = "rafx-dx12",
7        feature = "rafx-metal",
8        feature = "rafx-vulkan",
9        feature = "rafx-gles2",
10        feature = "rafx-gles3"
11    ))
12))]
13use crate::empty::RafxCommandPoolEmpty;
14#[cfg(feature = "rafx-gles2")]
15use crate::gles2::RafxCommandPoolGles2;
16#[cfg(feature = "rafx-gles3")]
17use crate::gles3::RafxCommandPoolGles3;
18#[cfg(feature = "rafx-metal")]
19use crate::metal::RafxCommandPoolMetal;
20#[cfg(feature = "rafx-vulkan")]
21use crate::vulkan::RafxCommandPoolVulkan;
22use crate::{RafxCommandBuffer, RafxCommandBufferDef, RafxDeviceContext, RafxResult};
23
24/// A pool of command buffers. A command pool is necessary to create a command buffer.
25///
26/// A command pool cannot be modified (including allocating from it) if one of its command buffers
27/// is being modified or in-use by the GPU.
28///
29/// Resetting a command pool clears all of the command buffers allocated from it, but the command
30/// buffers remain allocated.
31///
32/// The command pool must not be dropped while any of its command buffers are in use. However, it
33/// is ok to drop a command pool while command buffers are allocated, as long as those command
34/// buffers are never used again. (The command pool owns the memory the command buffer points to)
35pub enum RafxCommandPool {
36    #[cfg(feature = "rafx-dx12")]
37    Dx12(RafxCommandPoolDx12),
38    #[cfg(feature = "rafx-vulkan")]
39    Vk(RafxCommandPoolVulkan),
40    #[cfg(feature = "rafx-metal")]
41    Metal(RafxCommandPoolMetal),
42    #[cfg(feature = "rafx-gles2")]
43    Gles2(RafxCommandPoolGles2),
44    #[cfg(feature = "rafx-gles3")]
45    Gles3(RafxCommandPoolGles3),
46    #[cfg(any(
47        feature = "rafx-empty",
48        not(any(
49            feature = "rafx-dx12",
50            feature = "rafx-metal",
51            feature = "rafx-vulkan",
52            feature = "rafx-gles2",
53            feature = "rafx-gles3"
54        ))
55    ))]
56    Empty(RafxCommandPoolEmpty),
57}
58
59impl RafxCommandPool {
60    pub fn device_context(&self) -> RafxDeviceContext {
61        match self {
62            #[cfg(feature = "rafx-dx12")]
63            RafxCommandPool::Dx12(inner) => RafxDeviceContext::Dx12(inner.device_context().clone()),
64            #[cfg(feature = "rafx-vulkan")]
65            RafxCommandPool::Vk(inner) => RafxDeviceContext::Vk(inner.device_context().clone()),
66            #[cfg(feature = "rafx-metal")]
67            RafxCommandPool::Metal(inner) => {
68                RafxDeviceContext::Metal(inner.device_context().clone())
69            }
70            #[cfg(feature = "rafx-gles2")]
71            RafxCommandPool::Gles2(inner) => {
72                RafxDeviceContext::Gles2(inner.device_context().clone())
73            }
74            #[cfg(feature = "rafx-gles3")]
75            RafxCommandPool::Gles3(inner) => {
76                RafxDeviceContext::Gles3(inner.device_context().clone())
77            }
78            #[cfg(any(
79                feature = "rafx-empty",
80                not(any(
81                    feature = "rafx-dx12",
82                    feature = "rafx-metal",
83                    feature = "rafx-vulkan",
84                    feature = "rafx-gles2",
85                    feature = "rafx-gles3"
86                ))
87            ))]
88            RafxCommandPool::Empty(inner) => {
89                RafxDeviceContext::Empty(inner.device_context().clone())
90            }
91        }
92    }
93
94    /// Allocate a command buffer from the pool. This must not be called if a command buffer from
95    /// this pool is being written or is in-use by the GPU.
96    pub fn create_command_buffer(
97        &mut self,
98        command_buffer_def: &RafxCommandBufferDef,
99    ) -> RafxResult<RafxCommandBuffer> {
100        Ok(match self {
101            #[cfg(feature = "rafx-dx12")]
102            RafxCommandPool::Dx12(inner) => {
103                RafxCommandBuffer::Dx12(inner.create_command_buffer(command_buffer_def)?)
104            }
105            #[cfg(feature = "rafx-vulkan")]
106            RafxCommandPool::Vk(inner) => {
107                RafxCommandBuffer::Vk(inner.create_command_buffer(command_buffer_def)?)
108            }
109            #[cfg(feature = "rafx-metal")]
110            RafxCommandPool::Metal(inner) => {
111                RafxCommandBuffer::Metal(inner.create_command_buffer(command_buffer_def)?)
112            }
113            #[cfg(feature = "rafx-gles2")]
114            RafxCommandPool::Gles2(inner) => {
115                RafxCommandBuffer::Gles2(inner.create_command_buffer(command_buffer_def)?)
116            }
117            #[cfg(feature = "rafx-gles3")]
118            RafxCommandPool::Gles3(inner) => {
119                RafxCommandBuffer::Gles3(inner.create_command_buffer(command_buffer_def)?)
120            }
121            #[cfg(any(
122                feature = "rafx-empty",
123                not(any(
124                    feature = "rafx-dx12",
125                    feature = "rafx-metal",
126                    feature = "rafx-vulkan",
127                    feature = "rafx-gles2",
128                    feature = "rafx-gles3"
129                ))
130            ))]
131            RafxCommandPool::Empty(inner) => {
132                RafxCommandBuffer::Empty(inner.create_command_buffer(command_buffer_def)?)
133            }
134        })
135    }
136
137    /// Reset all command buffers to an "unwritten" state. This must not be called if any command
138    /// buffers allocated from this pool are in use by the GPU.
139    ///
140    /// This does not "free" allocated command buffers for reallocation.
141    pub fn reset_command_pool(&mut self) -> RafxResult<()> {
142        match self {
143            #[cfg(feature = "rafx-dx12")]
144            RafxCommandPool::Dx12(inner) => inner.reset_command_pool(),
145            #[cfg(feature = "rafx-vulkan")]
146            RafxCommandPool::Vk(inner) => inner.reset_command_pool(),
147            // metal does not have the concept of command buffer pools in the API
148            #[cfg(feature = "rafx-metal")]
149            RafxCommandPool::Metal(inner) => inner.reset_command_pool(),
150            #[cfg(feature = "rafx-gles2")]
151            RafxCommandPool::Gles2(inner) => inner.reset_command_pool(),
152            #[cfg(feature = "rafx-gles3")]
153            RafxCommandPool::Gles3(inner) => inner.reset_command_pool(),
154            #[cfg(any(
155                feature = "rafx-empty",
156                not(any(
157                    feature = "rafx-dx12",
158                    feature = "rafx-metal",
159                    feature = "rafx-vulkan",
160                    feature = "rafx-gles2",
161                    feature = "rafx-gles3"
162                ))
163            ))]
164            RafxCommandPool::Empty(inner) => inner.reset_command_pool(),
165        }
166    }
167
168    /// Get the underlying vulkan API object. This provides access to any internally created
169    /// vulkan objects.
170    #[cfg(feature = "rafx-dx12")]
171    pub fn dx12_command_pool(&self) -> Option<&RafxCommandPoolDx12> {
172        match self {
173            #[cfg(feature = "rafx-dx12")]
174            RafxCommandPool::Dx12(inner) => Some(inner),
175            #[cfg(feature = "rafx-vulkan")]
176            RafxCommandPool::Vk(_) => None,
177            #[cfg(feature = "rafx-metal")]
178            RafxCommandPool::Metal(_) => None,
179            #[cfg(feature = "rafx-gles2")]
180            RafxCommandPool::Gles2(_) => None,
181            #[cfg(feature = "rafx-gles3")]
182            RafxCommandPool::Gles3(_) => None,
183            #[cfg(any(
184                feature = "rafx-empty",
185                not(any(
186                    feature = "rafx-dx12",
187                    feature = "rafx-metal",
188                    feature = "rafx-vulkan",
189                    feature = "rafx-gles2",
190                    feature = "rafx-gles3"
191                ))
192            ))]
193            RafxCommandPool::Empty(_) => None,
194        }
195    }
196
197    /// Get the underlying vulkan API object. This provides access to any internally created
198    /// vulkan objects.
199    #[cfg(feature = "rafx-vulkan")]
200    pub fn vk_command_pool(&self) -> Option<&RafxCommandPoolVulkan> {
201        match self {
202            #[cfg(feature = "rafx-dx12")]
203            RafxCommandPool::Dx12(_) => None,
204            #[cfg(feature = "rafx-vulkan")]
205            RafxCommandPool::Vk(inner) => Some(inner),
206            #[cfg(feature = "rafx-metal")]
207            RafxCommandPool::Metal(_) => None,
208            #[cfg(feature = "rafx-gles2")]
209            RafxCommandPool::Gles2(_) => None,
210            #[cfg(feature = "rafx-gles3")]
211            RafxCommandPool::Gles3(_) => None,
212            #[cfg(any(
213                feature = "rafx-empty",
214                not(any(
215                    feature = "rafx-dx12",
216                    feature = "rafx-metal",
217                    feature = "rafx-vulkan",
218                    feature = "rafx-gles2",
219                    feature = "rafx-gles3"
220                ))
221            ))]
222            RafxCommandPool::Empty(_) => None,
223        }
224    }
225
226    /// Get the underlying metal API object. This provides access to any internally created
227    /// metal objects.
228    #[cfg(feature = "rafx-metal")]
229    pub fn metal_command_pool(&self) -> Option<&RafxCommandPoolMetal> {
230        match self {
231            #[cfg(feature = "rafx-dx12")]
232            RafxCommandPool::Dx12(_) => None,
233            #[cfg(feature = "rafx-vulkan")]
234            RafxCommandPool::Vk(_) => None,
235            #[cfg(feature = "rafx-metal")]
236            RafxCommandPool::Metal(inner) => Some(inner),
237            #[cfg(feature = "rafx-gles2")]
238            RafxCommandPool::Gles2(_) => None,
239            #[cfg(feature = "rafx-gles3")]
240            RafxCommandPool::Gles3(_) => None,
241            #[cfg(any(
242                feature = "rafx-empty",
243                not(any(
244                    feature = "rafx-dx12",
245                    feature = "rafx-metal",
246                    feature = "rafx-vulkan",
247                    feature = "rafx-gles2",
248                    feature = "rafx-gles3"
249                ))
250            ))]
251            RafxCommandPool::Empty(_) => None,
252        }
253    }
254
255    /// Get the underlying gl API object. This provides access to any internally created
256    /// metal objects.
257    #[cfg(feature = "rafx-gles2")]
258    pub fn gles2_command_pool(&self) -> Option<&RafxCommandPoolGles2> {
259        match self {
260            #[cfg(feature = "rafx-dx12")]
261            RafxCommandPool::Dx12(_) => None,
262            #[cfg(feature = "rafx-vulkan")]
263            RafxCommandPool::Vk(_) => None,
264            #[cfg(feature = "rafx-metal")]
265            RafxCommandPool::Metal(_) => None,
266            #[cfg(feature = "rafx-gles2")]
267            RafxCommandPool::Gles2(inner) => Some(inner),
268            #[cfg(feature = "rafx-gles3")]
269            RafxCommandPool::Gles3(_) => None,
270            #[cfg(any(
271                feature = "rafx-empty",
272                not(any(
273                    feature = "rafx-dx12",
274                    feature = "rafx-metal",
275                    feature = "rafx-vulkan",
276                    feature = "rafx-gles2",
277                    feature = "rafx-gles3"
278                ))
279            ))]
280            RafxCommandPool::Empty(_) => None,
281        }
282    }
283
284    /// Get the underlying gl API object. This provides access to any internally created
285    /// metal objects.
286    #[cfg(feature = "rafx-gles3")]
287    pub fn gles3_command_pool(&self) -> Option<&RafxCommandPoolGles3> {
288        match self {
289            #[cfg(feature = "rafx-dx12")]
290            RafxCommandPool::Dx12(_) => None,
291            #[cfg(feature = "rafx-vulkan")]
292            RafxCommandPool::Vk(_) => None,
293            #[cfg(feature = "rafx-metal")]
294            RafxCommandPool::Metal(_) => None,
295            #[cfg(feature = "rafx-gles2")]
296            RafxCommandPool::Gles2(_) => None,
297            #[cfg(feature = "rafx-gles3")]
298            RafxCommandPool::Gles3(inner) => Some(inner),
299            #[cfg(any(
300                feature = "rafx-empty",
301                not(any(
302                    feature = "rafx-dx12",
303                    feature = "rafx-metal",
304                    feature = "rafx-vulkan",
305                    feature = "rafx-gles2",
306                    feature = "rafx-gles3"
307                ))
308            ))]
309            RafxCommandPool::Empty(_) => None,
310        }
311    }
312
313    #[cfg(any(
314        feature = "rafx-empty",
315        not(any(
316            feature = "rafx-dx12",
317            feature = "rafx-metal",
318            feature = "rafx-vulkan",
319            feature = "rafx-gles2",
320            feature = "rafx-gles3"
321        ))
322    ))]
323    pub fn empty_command_pool(&self) -> Option<&RafxCommandPoolEmpty> {
324        match self {
325            #[cfg(feature = "rafx-dx12")]
326            RafxCommandPool::Dx12(_) => None,
327            #[cfg(feature = "rafx-vulkan")]
328            RafxCommandPool::Vk(_) => None,
329            #[cfg(feature = "rafx-metal")]
330            RafxCommandPool::Metal(_) => None,
331            #[cfg(feature = "rafx-gles2")]
332            RafxCommandPool::Gles2(_) => None,
333            #[cfg(any(
334                feature = "rafx-empty",
335                not(any(
336                    feature = "rafx-dx12",
337                    feature = "rafx-metal",
338                    feature = "rafx-vulkan",
339                    feature = "rafx-gles2",
340                    feature = "rafx-gles3"
341                ))
342            ))]
343            RafxCommandPool::Empty(inner) => Some(inner),
344        }
345    }
346}