vyre_driver_wgpu/engine/
graph.rs1use crate::buffer::GpuBufferHandle;
8use crate::pipeline::compound::CompoundResource;
9use crate::pipeline::WgpuPipeline;
10use smallvec::SmallVec;
11use vyre_driver::{BackendError, DispatchConfig};
12
13#[derive(Clone)]
15pub enum GpuResource {
16 Borrowed(Vec<u8>),
18 Resident(GpuBufferHandle),
20}
21
22impl From<Vec<u8>> for GpuResource {
23 fn from(bytes: Vec<u8>) -> Self {
24 Self::Borrowed(bytes)
25 }
26}
27
28impl From<GpuBufferHandle> for GpuResource {
29 fn from(handle: GpuBufferHandle) -> Self {
30 Self::Resident(handle)
31 }
32}
33
34#[derive(Default)]
36pub struct GpuDispatchGraph {
37 ops: SmallVec<[GraphOp; 8]>,
38}
39
40#[derive(Clone)]
41struct GraphOp {
42 pipeline: WgpuPipeline,
43 input: GpuResource,
44}
45
46impl GpuDispatchGraph {
47 #[must_use]
49 pub fn new() -> Self {
50 Self {
51 ops: SmallVec::new(),
52 }
53 }
54
55 pub fn push(&mut self, pipeline: WgpuPipeline, input: impl Into<GpuResource>) {
57 self.ops.push(GraphOp {
58 pipeline,
59 input: input.into(),
60 });
61 }
62
63 #[must_use]
65 pub fn len(&self) -> usize {
66 self.ops.len()
67 }
68
69 #[must_use]
71 pub fn is_empty(&self) -> bool {
72 self.ops.is_empty()
73 }
74
75 pub fn dispatch(&self, config: &DispatchConfig) -> Result<Vec<Vec<Vec<u8>>>, BackendError> {
82 if self.ops.is_empty() {
83 return Ok(Vec::new());
84 }
85
86 let mut internal_requests: SmallVec<[(&WgpuPipeline, CompoundResource<'_>); 8]> =
90 SmallVec::with_capacity(self.ops.len());
91 for op in &self.ops {
92 let res = match &op.input {
93 GpuResource::Borrowed(bytes) => CompoundResource::Borrowed(bytes),
94 GpuResource::Resident(handle) => CompoundResource::Resident(handle.id()),
95 };
96 internal_requests.push((&op.pipeline, res));
97 }
98
99 WgpuPipeline::dispatch_compound_borrowed(&internal_requests, config)
100 }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
105pub struct LaunchAccounting {
106 pub sequential_submissions: usize,
108 pub graph_submissions: usize,
110}
111
112impl LaunchAccounting {
113 #[must_use]
115 pub fn reduction_factor(self) -> usize {
116 self.sequential_submissions / self.graph_submissions.max(1)
117 }
118}
119
120#[must_use]
122pub fn launch_accounting(op_count: usize) -> LaunchAccounting {
123 LaunchAccounting {
124 sequential_submissions: op_count,
125 graph_submissions: usize::from(op_count > 0),
126 }
127}