1use {
4 crate::{buffer::*, capability::*, core::Device, family::FamilyId},
5 rendy_core::hal::{device::Device as _, pool::CommandPool as _, Backend},
6};
7
8#[derive(Debug)]
12pub struct CommandPool<B: Backend, C = QueueType, R = NoIndividualReset> {
13 raw: B::CommandPool,
14 capability: C,
15 reset: R,
16 family: FamilyId,
17 relevant: relevant::Relevant,
18}
19
20family_owned!(CommandPool<B, C, R>);
21
22impl<B, C, R> CommandPool<B, C, R>
23where
24 B: Backend,
25 R: Reset,
26{
27 pub unsafe fn create(
35 family: FamilyId,
36 capability: C,
37 device: &Device<B>,
38 ) -> Result<Self, rendy_core::hal::device::OutOfMemory>
39 where
40 R: Reset,
41 C: Capability,
42 {
43 let reset = R::default();
44 let raw = device.create_command_pool(
45 rendy_core::hal::queue::QueueFamilyId(family.index),
46 reset.flags(),
47 )?;
48 Ok(CommandPool::from_raw(raw, capability, reset, family))
49 }
50
51 pub unsafe fn from_raw(raw: B::CommandPool, capability: C, reset: R, family: FamilyId) -> Self {
60 CommandPool {
61 raw,
62 capability,
63 reset,
64 family,
65 relevant: relevant::Relevant,
66 }
67 }
68
69 pub fn allocate_buffers<L: Level>(
71 &mut self,
72 count: usize,
73 ) -> Vec<CommandBuffer<B, C, InitialState, L, R>>
74 where
75 L: Level,
76 C: Capability,
77 {
78 let level = L::default();
79
80 let buffers = unsafe { self.raw.allocate_vec(count, level.raw_level()) };
81
82 buffers
83 .into_iter()
84 .map(|raw| unsafe {
85 CommandBuffer::from_raw(
86 raw,
87 self.capability,
88 InitialState,
89 level,
90 self.reset,
91 self.family,
92 )
93 })
94 .collect()
95 }
96
97 pub unsafe fn free_buffers(
101 &mut self,
102 buffers: impl IntoIterator<Item = CommandBuffer<B, C, impl Resettable, impl Level, R>>,
103 ) {
104 let buffers = buffers
105 .into_iter()
106 .map(|buffer| buffer.into_raw())
107 .collect::<Vec<_>>();
108
109 self.raw.free(buffers);
110 }
111
112 pub unsafe fn reset(&mut self) {
119 rendy_core::hal::pool::CommandPool::reset(&mut self.raw, false);
120 }
121
122 pub unsafe fn dispose(self, device: &Device<B>) {
128 self.assert_device_owner(device);
129 device.destroy_command_pool(self.raw);
130 self.relevant.dispose();
131 }
132
133 pub fn with_queue_type(self) -> CommandPool<B, QueueType, R>
135 where
136 C: Capability,
137 {
138 CommandPool {
139 raw: self.raw,
140 capability: self.capability.into_queue_type(),
141 reset: self.reset,
142 family: self.family,
143 relevant: self.relevant,
144 }
145 }
146
147 pub fn with_capability<U>(self) -> Result<CommandPool<B, U, R>, Self>
149 where
150 C: Supports<U>,
151 {
152 if let Some(capability) = self.capability.supports() {
153 Ok(CommandPool {
154 raw: self.raw,
155 capability,
156 reset: self.reset,
157 family: self.family,
158 relevant: self.relevant,
159 })
160 } else {
161 Err(self)
162 }
163 }
164}