1use std::sync::Arc;
25
26use svod_dtype::DeviceSpec;
27
28use crate::buffer::Buffer;
29use crate::device::Program;
30use crate::error::Result;
31use crate::sync::TimelineSignal;
32
33#[derive(Debug, Clone)]
35pub struct ExecParams {
36 pub global_size: [usize; 3],
38 pub local_size: Option<[usize; 3]>,
40 pub vals: Vec<i64>,
42}
43
44impl ExecParams {
45 pub fn new_1d(global: usize, local: usize) -> Self {
47 Self { global_size: [global, 1, 1], local_size: Some([local, 1, 1]), vals: Vec::new() }
48 }
49
50 pub fn new_2d(global: [usize; 2], local: [usize; 2]) -> Self {
52 Self { global_size: [global[0], global[1], 1], local_size: Some([local[0], local[1], 1]), vals: Vec::new() }
53 }
54
55 pub fn new_3d(global: [usize; 3], local: [usize; 3]) -> Self {
57 Self { global_size: global, local_size: Some(local), vals: Vec::new() }
58 }
59
60 pub fn with_vals(mut self, vals: Vec<i64>) -> Self {
62 self.vals = vals;
63 self
64 }
65}
66
67impl Default for ExecParams {
68 fn default() -> Self {
69 Self { global_size: [1, 1, 1], local_size: Some([1, 1, 1]), vals: Vec::new() }
70 }
71}
72
73pub trait HardwareQueue: Send + std::fmt::Debug {
83 type Signal: TimelineSignal;
85
86 fn wait(&mut self, signal: &Self::Signal, value: u64) -> &mut Self;
91
92 fn signal(&mut self, signal: &Self::Signal, value: u64) -> &mut Self;
96
97 fn exec(&mut self, program: Arc<dyn Program>, buffers: &[&Buffer], params: &ExecParams) -> &mut Self;
111
112 fn copy(&mut self, dst: &Buffer, src: &Buffer) -> &mut Self;
117
118 fn memory_barrier(&mut self) -> &mut Self;
123
124 fn submit(&mut self) -> Result<()>;
129
130 fn device(&self) -> &DeviceSpec;
132}
133
134pub trait QueueFactory: Send + Sync + std::fmt::Debug {
139 type Queue: HardwareQueue;
141
142 type Signal: TimelineSignal;
144
145 fn create_compute_queue(&self) -> Result<Self::Queue>;
147
148 fn create_copy_queue(&self) -> Result<Option<Self::Queue>>;
152
153 fn create_signal(&self) -> Result<Arc<Self::Signal>>;
155
156 fn device(&self) -> &DeviceSpec;
158}
159
160pub struct DynQueue {
165 inner: Box<dyn DynQueueInner>,
166}
167
168impl std::fmt::Debug for DynQueue {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
170 f.debug_struct("DynQueue").field("device", &self.inner.device()).finish()
171 }
172}
173
174impl DynQueue {
175 pub fn new<Q: HardwareQueue + 'static>(queue: Q) -> Self
177 where
178 Q::Signal: 'static,
179 {
180 Self { inner: Box::new(DynQueueWrapper { queue, _phantom: std::marker::PhantomData }) }
181 }
182
183 pub fn wait(&mut self, signal: &dyn TimelineSignal, value: u64) -> &mut Self {
185 self.inner.wait_dyn(signal, value);
186 self
187 }
188
189 pub fn signal(&mut self, signal: &dyn TimelineSignal, value: u64) -> &mut Self {
191 self.inner.signal_dyn(signal, value);
192 self
193 }
194
195 pub fn exec(&mut self, program: Arc<dyn Program>, buffers: &[&Buffer], params: &ExecParams) -> &mut Self {
197 self.inner.exec_dyn(program, buffers, params);
198 self
199 }
200
201 pub fn copy(&mut self, dst: &Buffer, src: &Buffer) -> &mut Self {
203 self.inner.copy_dyn(dst, src);
204 self
205 }
206
207 pub fn memory_barrier(&mut self) -> &mut Self {
209 self.inner.memory_barrier_dyn();
210 self
211 }
212
213 pub fn submit(&mut self) -> Result<()> {
215 self.inner.submit_dyn()
216 }
217
218 pub fn device(&self) -> &DeviceSpec {
220 self.inner.device()
221 }
222}
223
224trait DynQueueInner: Send + std::fmt::Debug {
226 fn wait_dyn(&mut self, signal: &dyn TimelineSignal, value: u64);
227 fn signal_dyn(&mut self, signal: &dyn TimelineSignal, value: u64);
228 fn exec_dyn(&mut self, program: Arc<dyn Program>, buffers: &[&Buffer], params: &ExecParams);
229 fn copy_dyn(&mut self, dst: &Buffer, src: &Buffer);
230 fn memory_barrier_dyn(&mut self);
231 fn submit_dyn(&mut self) -> Result<()>;
232 fn device(&self) -> &DeviceSpec;
233}
234
235struct DynQueueWrapper<Q: HardwareQueue> {
237 queue: Q,
238 _phantom: std::marker::PhantomData<Q::Signal>,
239}
240
241impl<Q: HardwareQueue> std::fmt::Debug for DynQueueWrapper<Q> {
242 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
243 f.debug_struct("DynQueueWrapper").field("queue", &self.queue).finish()
244 }
245}
246
247impl<Q: HardwareQueue + 'static> DynQueueInner for DynQueueWrapper<Q>
248where
249 Q::Signal: 'static,
250{
251 fn wait_dyn(&mut self, signal: &dyn TimelineSignal, value: u64) {
252 let signal = signal.as_any().downcast_ref::<Q::Signal>().unwrap_or_else(|| {
253 panic!("DynQueue wait signal type mismatch: queue device {:?}, signal {:?}", self.queue.device(), signal)
254 });
255 self.queue.wait(signal, value);
256 }
257
258 fn signal_dyn(&mut self, signal: &dyn TimelineSignal, value: u64) {
259 let signal = signal.as_any().downcast_ref::<Q::Signal>().unwrap_or_else(|| {
260 panic!("DynQueue signal type mismatch: queue device {:?}, signal {:?}", self.queue.device(), signal)
261 });
262 self.queue.signal(signal, value);
263 }
264
265 fn exec_dyn(&mut self, program: Arc<dyn Program>, buffers: &[&Buffer], params: &ExecParams) {
266 self.queue.exec(program, buffers, params);
267 }
268
269 fn copy_dyn(&mut self, dst: &Buffer, src: &Buffer) {
270 self.queue.copy(dst, src);
271 }
272
273 fn memory_barrier_dyn(&mut self) {
274 self.queue.memory_barrier();
275 }
276
277 fn submit_dyn(&mut self) -> Result<()> {
278 self.queue.submit()
279 }
280
281 fn device(&self) -> &DeviceSpec {
282 self.queue.device()
283 }
284}