1 // Copyright 2023 Google LLC
2 //
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #[cxx::bridge(namespace = "vello_cpp")]
7 mod ffi {
8 // === vello_shaders FFI types ===
9
10 enum ShaderStage {
11 Backdrop,
12 BackdropDyn,
13 BboxClear,
14 Binning,
15 ClipLeaf,
16 ClipReduce,
17 Coarse,
18 DrawLeaf,
19 DrawReduce,
20 FineArea,
21 FineMsaa16,
22 FineMsaa8,
23 FineAreaR8,
24 FineMsaa16R8,
25 FineMsaa8R8,
26 Flatten,
27 PathCount,
28 PathCountSetup,
29 PathTiling,
30 PathTilingSetup,
31 Pathseg,
32 PathtagReduce,
33 PathtagReduce2,
34 PathtagScan1,
35 PathtagScanLarge,
36 PathtagScanSmall,
37 TileAlloc,
38 }
39
40 enum BindType {
41 Buffer,
42 BufReadOnly,
43 Uniform,
44 Image,
45 ImageRead,
46 }
47
48 struct WorkgroupBufferInfo {
49 size_in_bytes: u32,
50 index: u32,
51 }
52
53 // === vello_encoding FFI types ===
54
55 /// Represents a 3x3 affine transformation matrix. The coordinates are laid out using the
56 /// following column-major construction, where the entries
57 ///
58 /// [a, b, c, d, e, f]
59 ///
60 /// correspond to the matrix
61 ///
62 /// | a c e |
63 /// | b d f |
64 /// | 0 0 1 |
65 ///
66 struct Affine {
67 matrix: [f32; 6],
68 }
69
70 struct Color {
71 r: u8,
72 g: u8,
73 b: u8,
74 a: u8,
75 }
76
77 enum BrushKind {
78 Solid,
79 }
80
81 struct BrushData {
82 solid: Color,
83 }
84
85 struct Brush {
86 kind: BrushKind,
87 data: BrushData,
88 }
89
90 enum Fill {
91 NonZero,
92 EvenOdd,
93 }
94
95 enum CapStyle {
96 Butt,
97 Square,
98 Round,
99 }
100
101 enum JoinStyle {
102 Bevel,
103 Miter,
104 Round,
105 }
106
107 struct Stroke {
108 width: f32,
109 miter_limit: f32,
110 cap: CapStyle,
111 join: JoinStyle,
112 }
113
114 #[derive(Copy, Clone, Default, Debug)]
115 struct Point {
116 x: f32,
117 y: f32,
118 }
119
120 #[derive(Debug)]
121 enum PathVerb {
122 MoveTo,
123 LineTo,
124 QuadTo,
125 CurveTo,
126 Close,
127 }
128
129 #[derive(Default, Debug)]
130 struct PathElement {
131 verb: PathVerb,
132 points: [Point; 4],
133 }
134
135 // Types that contain dispatch metadata
136
137 struct WorkgroupSize {
138 x: u32,
139 y: u32,
140 z: u32,
141 }
142
143 struct DispatchInfo {
144 use_large_path_scan: bool,
145
146 // Dispatch workgroup counts for each pipeline
147 path_reduce: WorkgroupSize,
148 path_reduce2: WorkgroupSize,
149 path_scan1: WorkgroupSize,
150 path_scan: WorkgroupSize,
151 bbox_clear: WorkgroupSize,
152 flatten: WorkgroupSize,
153 draw_reduce: WorkgroupSize,
154 draw_leaf: WorkgroupSize,
155 clip_reduce: WorkgroupSize,
156 clip_leaf: WorkgroupSize,
157 binning: WorkgroupSize,
158 tile_alloc: WorkgroupSize,
159 path_count_setup: WorkgroupSize,
160 // Note: `path_count` must use an indirect dispatch
161 backdrop: WorkgroupSize,
162 coarse: WorkgroupSize,
163 path_tiling_setup: WorkgroupSize,
164 // Note: `path_tiling` must use an indirect dispatch
165 fine: WorkgroupSize,
166 }
167
168 /// Computed sizes for all buffers.
169 struct BufferSizes {
170 // Known size buffers
171 path_reduced: u32,
172 path_reduced2: u32,
173 path_reduced_scan: u32,
174 path_monoids: u32,
175 path_bboxes: u32,
176 draw_reduced: u32,
177 draw_monoids: u32,
178 info: u32,
179 clip_inps: u32,
180 clip_els: u32,
181 clip_bics: u32,
182 clip_bboxes: u32,
183 draw_bboxes: u32,
184 bump_alloc: u32,
185 indirect_count: u32,
186 bin_headers: u32,
187 paths: u32,
188 // Bump allocated buffers
189 lines: u32,
190 bin_data: u32,
191 tiles: u32,
192 seg_counts: u32,
193 segments: u32,
194 ptcl: u32,
195 }
196
197 extern "Rust" {
198 type Shader;
shader(stage: ShaderStage) -> &'static Shader199 fn shader(stage: ShaderStage) -> &'static Shader;
name(self: &Shader) -> &str200 fn name(self: &Shader) -> &str;
workgroup_size(self: &Shader) -> WorkgroupSize201 fn workgroup_size(self: &Shader) -> WorkgroupSize;
bindings(self: &Shader) -> Vec<BindType>202 fn bindings(self: &Shader) -> Vec<BindType>;
workgroup_buffers(self: &Shader) -> Vec<WorkgroupBufferInfo>203 fn workgroup_buffers(self: &Shader) -> Vec<WorkgroupBufferInfo>;
204 #[cfg(feature = "wgsl")]
wgsl(self: &Shader) -> &str205 fn wgsl(self: &Shader) -> &str;
206 #[cfg(feature = "msl")]
msl(self: &Shader) -> &str207 fn msl(self: &Shader) -> &str;
208
209 type Encoding;
new_encoding() -> Box<Encoding>210 fn new_encoding() -> Box<Encoding>;
is_empty(self: &Encoding) -> bool211 fn is_empty(self: &Encoding) -> bool;
reset(self: &mut Encoding)212 fn reset(self: &mut Encoding);
fill( self: &mut Encoding, style: Fill, transform: Affine, brush: &Brush, path_iter: Pin<&mut PathIterator>, )213 fn fill(
214 self: &mut Encoding,
215 style: Fill,
216 transform: Affine,
217 brush: &Brush,
218 path_iter: Pin<&mut PathIterator>,
219 );
stroke( self: &mut Encoding, style: &Stroke, transform: Affine, brush: &Brush, path_iter: Pin<&mut PathIterator>, )220 fn stroke(
221 self: &mut Encoding,
222 style: &Stroke,
223 transform: Affine,
224 brush: &Brush,
225 path_iter: Pin<&mut PathIterator>,
226 );
begin_clip(self: &mut Encoding, transform: Affine, path_iter: Pin<&mut PathIterator>)227 fn begin_clip(self: &mut Encoding, transform: Affine, path_iter: Pin<&mut PathIterator>);
end_clip(self: &mut Encoding)228 fn end_clip(self: &mut Encoding);
append(self: &mut Encoding, other: &Encoding)229 fn append(self: &mut Encoding, other: &Encoding);
prepare_render( self: &Encoding, width: u32, height: u32, background: &Color, ) -> Box<RenderConfiguration>230 fn prepare_render(
231 self: &Encoding,
232 width: u32,
233 height: u32,
234 background: &Color,
235 ) -> Box<RenderConfiguration>;
236
237 /// Resolved scene encoding metadata that can be used to initiate pipeline dispatches.
238 type RenderConfiguration;
config_uniform_buffer_size(self: &RenderConfiguration) -> usize239 fn config_uniform_buffer_size(self: &RenderConfiguration) -> usize;
scene_buffer_size(self: &RenderConfiguration) -> usize240 fn scene_buffer_size(self: &RenderConfiguration) -> usize;
write_config_uniform_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool241 fn write_config_uniform_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool;
write_scene_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool242 fn write_scene_buffer(self: &RenderConfiguration, out_buffer: &mut [u8]) -> bool;
workgroup_counts(self: &RenderConfiguration) -> DispatchInfo243 fn workgroup_counts(self: &RenderConfiguration) -> DispatchInfo;
buffer_sizes(self: &RenderConfiguration) -> BufferSizes244 fn buffer_sizes(self: &RenderConfiguration) -> BufferSizes;
245
246 /// Sample mask lookup tables used in MSAA modes. This data can be computed once and reused
247 /// across all renders.
build_mask_lut_16() -> Vec<u8>248 fn build_mask_lut_16() -> Vec<u8>;
build_mask_lut_8() -> Vec<u8>249 fn build_mask_lut_8() -> Vec<u8>;
250 }
251
252 unsafe extern "C++" {
253 include!("third_party/vello/cpp/path_iterator.h");
254
255 type PathIterator;
next_element(self: Pin<&mut PathIterator>, out_elem: *mut PathElement) -> bool256 unsafe fn next_element(self: Pin<&mut PathIterator>, out_elem: *mut PathElement) -> bool;
257 }
258 }
259
260 mod encoding;
261 mod shaders;
262
263 use {
264 encoding::{new_encoding, Encoding, RenderConfiguration},
265 shaders::{shader, Shader},
266 };
267
build_mask_lut_16() -> Vec<u8>268 fn build_mask_lut_16() -> Vec<u8> {
269 vello_encoding::make_mask_lut_16()
270 }
271
build_mask_lut_8() -> Vec<u8>272 fn build_mask_lut_8() -> Vec<u8> {
273 vello_encoding::make_mask_lut()
274 }
275