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 use crate::ffi;
7 use vello_shaders::{BindType, WorkgroupBufferInfo};
8
9 pub(crate) struct Shader(&'static vello_shaders::ComputeShader<'static>);
10
11 impl Shader {
name(&self) -> &str12 pub fn name(&self) -> &str {
13 &self.0.name
14 }
15
workgroup_size(&self) -> ffi::WorkgroupSize16 pub fn workgroup_size(&self) -> ffi::WorkgroupSize {
17 self.0.workgroup_size.into()
18 }
19
bindings(&self) -> Vec<ffi::BindType>20 pub fn bindings(&self) -> Vec<ffi::BindType> {
21 self.0.bindings.iter().map(|t| t.into()).collect()
22 }
23
workgroup_buffers(&self) -> Vec<ffi::WorkgroupBufferInfo>24 pub fn workgroup_buffers(&self) -> Vec<ffi::WorkgroupBufferInfo> {
25 self.0.workgroup_buffers.iter().map(|t| t.into()).collect()
26 }
27
28 #[cfg(feature = "wgsl")]
wgsl(&self) -> &str29 pub fn wgsl(&self) -> &str {
30 &self.0.wgsl.code
31 }
32
33 #[cfg(feature = "msl")]
msl(&self) -> &str34 pub fn msl(&self) -> &str {
35 &self.0.msl.code
36 }
37 }
38
39 macro_rules! decl_shader {
40 ($name:ident, $field:tt) => {
41 const $name: Shader = Shader(&vello_shaders::SHADERS.$field);
42 };
43 }
44
45 decl_shader!(BACKDROP, backdrop);
46 decl_shader!(BACKDROP_DYN, backdrop_dyn);
47 decl_shader!(BBOX_CLEAR, bbox_clear);
48 decl_shader!(BINNING, binning);
49 decl_shader!(CLIP_LEAF, clip_leaf);
50 decl_shader!(CLIP_REDUCE, clip_reduce);
51 decl_shader!(COARSE, coarse);
52 decl_shader!(DRAW_LEAF, draw_leaf);
53 decl_shader!(DRAW_REDUCE, draw_reduce);
54 decl_shader!(FINE_AREA, fine_area);
55 decl_shader!(FINE_MSAA16, fine_msaa16);
56 decl_shader!(FINE_MSAA8, fine_msaa8);
57 decl_shader!(FINE_AREA_R8, fine_area_r8);
58 decl_shader!(FINE_MSAA16_R8, fine_msaa16_r8);
59 decl_shader!(FINE_MSAA8_R8, fine_msaa8_r8);
60 decl_shader!(FLATTEN, flatten);
61 decl_shader!(PATH_COUNT, path_count);
62 decl_shader!(PATH_COUNT_SETUP, path_count_setup);
63 decl_shader!(PATH_TILING, path_tiling);
64 decl_shader!(PATH_TILING_SETUP, path_tiling_setup);
65 decl_shader!(PATHTAG_REDUCE, pathtag_reduce);
66 decl_shader!(PATHTAG_REDUCE2, pathtag_reduce2);
67 decl_shader!(PATHTAG_SCAN1, pathtag_scan1);
68 decl_shader!(PATHTAG_SCAN_LARGE, pathtag_scan_large);
69 decl_shader!(PATHTAG_SCAN_SMALL, pathtag_scan_small);
70 decl_shader!(TILE_ALLOC, tile_alloc);
71
shader(stage: ffi::ShaderStage) -> &'static Shader72 pub(crate) fn shader(stage: ffi::ShaderStage) -> &'static Shader {
73 match stage {
74 ffi::ShaderStage::Backdrop => &BACKDROP,
75 ffi::ShaderStage::BackdropDyn => &BACKDROP_DYN,
76 ffi::ShaderStage::BboxClear => &BBOX_CLEAR,
77 ffi::ShaderStage::Binning => &BINNING,
78 ffi::ShaderStage::ClipLeaf => &CLIP_LEAF,
79 ffi::ShaderStage::ClipReduce => &CLIP_REDUCE,
80 ffi::ShaderStage::Coarse => &COARSE,
81 ffi::ShaderStage::DrawLeaf => &DRAW_LEAF,
82 ffi::ShaderStage::DrawReduce => &DRAW_REDUCE,
83 ffi::ShaderStage::FineArea => &FINE_AREA,
84 ffi::ShaderStage::FineMsaa16 => &FINE_MSAA16,
85 ffi::ShaderStage::FineMsaa8 => &FINE_MSAA8,
86 ffi::ShaderStage::FineAreaR8 => &FINE_AREA_R8,
87 ffi::ShaderStage::FineMsaa16R8 => &FINE_MSAA16_R8,
88 ffi::ShaderStage::FineMsaa8R8 => &FINE_MSAA8_R8,
89 ffi::ShaderStage::Flatten => &FLATTEN,
90 ffi::ShaderStage::PathCount => &PATH_COUNT,
91 ffi::ShaderStage::PathCountSetup => &PATH_COUNT_SETUP,
92 ffi::ShaderStage::PathTiling => &PATH_TILING,
93 ffi::ShaderStage::PathTilingSetup => &PATH_TILING_SETUP,
94 ffi::ShaderStage::PathtagReduce => &PATHTAG_REDUCE,
95 ffi::ShaderStage::PathtagReduce2 => &PATHTAG_REDUCE2,
96 ffi::ShaderStage::PathtagScan1 => &PATHTAG_SCAN1,
97 ffi::ShaderStage::PathtagScanLarge => &PATHTAG_SCAN_LARGE,
98 ffi::ShaderStage::PathtagScanSmall => &PATHTAG_SCAN_SMALL,
99 ffi::ShaderStage::TileAlloc => &TILE_ALLOC,
100 _ => unreachable!(),
101 }
102 }
103
104 impl From<&BindType> for ffi::BindType {
from(src: &BindType) -> Self105 fn from(src: &BindType) -> Self {
106 match src {
107 BindType::Buffer => Self::Buffer,
108 BindType::BufReadOnly => Self::BufReadOnly,
109 BindType::Uniform => Self::Uniform,
110 BindType::Image => Self::Image,
111 BindType::ImageRead => Self::ImageRead,
112 }
113 }
114 }
115
116 impl From<&WorkgroupBufferInfo> for ffi::WorkgroupBufferInfo {
from(src: &WorkgroupBufferInfo) -> Self117 fn from(src: &WorkgroupBufferInfo) -> Self {
118 Self {
119 size_in_bytes: src.size_in_bytes,
120 index: src.index,
121 }
122 }
123 }
124
125 impl From<[u32; 3]> for ffi::WorkgroupSize {
from(src: [u32; 3]) -> Self126 fn from(src: [u32; 3]) -> Self {
127 Self {
128 x: src[0],
129 y: src[1],
130 z: src[2],
131 }
132 }
133 }
134