mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-09 20:31:29 +11:00
Use 'C style' preprocessing in piet-wgsl (#194)
This lets us use https://github.com/wgsl-analyzer/wgsl-analyzer for writing the wgsl files. The imports (for wgsl-analyzer) have to be machine specific at the moment - to use this you need to configure .vscode/settings.json yourself. The alternative is to point them at static files on GitHub, which is tempting to make things easier, but would potentially go out of sync with what is actually used.
This commit is contained in:
parent
b42679c675
commit
afa706bd7e
10
.vscode/settings.json
vendored
Normal file
10
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"wgsl-analyzer.customImports": {
|
||||
// Update as appropriate to proper path
|
||||
// temporary solution
|
||||
// "config": "file:C:\\Users\\Daniel\\Documents\\repositories\\linebender\\piet-gpu\\piet-wgsl\\shader\\shared\\config.wgsl",
|
||||
// "segment": "file:C:\\Users\\Daniel\\Documents\\repositories\\linebender\\piet-gpu\\piet-wgsl\\shader\\shared\\segment.wgsl",
|
||||
// "pathtag": "file:C:\\Users\\Daniel\\Documents\\repositories\\linebender\\piet-gpu\\piet-wgsl\\shader\\shared\\pathtag.wgsl"
|
||||
},
|
||||
"wgsl-analyzer.diagnostics.nagaVersion": "main"
|
||||
}
|
189
Cargo.lock
generated
189
Cargo.lock
generated
|
@ -122,15 +122,6 @@ version = "0.1.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.11.1"
|
||||
|
@ -230,9 +221,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.22"
|
||||
version = "3.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
|
||||
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
@ -240,7 +231,7 @@ dependencies = [
|
|||
"indexmap",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.15.1",
|
||||
"textwrap 0.16.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -334,15 +325,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
|
@ -352,16 +334,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
|
@ -449,16 +421,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
|
@ -559,16 +521,6 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
|
@ -648,21 +600,6 @@ version = "1.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "handlebars"
|
||||
version = "4.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433e4ab33f1213cdc25b5fa45c76881240cfe79284cf2b395e8b9e312a30a2fd"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
|
@ -885,14 +822,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
|
||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.36.1",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1137,50 +1074,6 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pgpu-render"
|
||||
version = "0.1.0"
|
||||
|
@ -1199,7 +1092,7 @@ name = "piet-gpu"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"clap 3.2.22",
|
||||
"clap 3.2.23",
|
||||
"kurbo 0.8.3",
|
||||
"ndk 0.3.0",
|
||||
"ndk-glue 0.3.0",
|
||||
|
@ -1249,7 +1142,7 @@ name = "piet-gpu-tests"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"clap 3.2.22",
|
||||
"clap 3.2.23",
|
||||
"kurbo 0.7.1",
|
||||
"piet-gpu",
|
||||
"piet-gpu-hal",
|
||||
|
@ -1281,13 +1174,10 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"env_logger",
|
||||
"futures-intrusive",
|
||||
"handlebars",
|
||||
"parking_lot",
|
||||
"piet-scene",
|
||||
"png",
|
||||
"pollster",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wgpu",
|
||||
]
|
||||
|
||||
|
@ -1550,15 +1440,6 @@ version = "1.0.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
|
@ -1573,18 +1454,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.145"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.145"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1593,26 +1474,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.86"
|
||||
version = "1.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
|
||||
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.6"
|
||||
|
@ -1726,9 +1596,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.15.1"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
|
@ -1759,18 +1629,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
|
@ -1807,17 +1665,6 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
|
@ -2206,9 +2053,9 @@ checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
|||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
version = "0.27.4"
|
||||
version = "0.27.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37f64802920c4c35d12a53dad5e0c55bbc3004d8dc4f2e4dd64ad02c5665d7aa"
|
||||
checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cocoa",
|
||||
|
|
|
@ -12,9 +12,6 @@ pollster = "0.2.5"
|
|||
futures-intrusive = "0.4.1"
|
||||
parking_lot = "0.12"
|
||||
bytemuck = { version = "1.12.1", features = ["derive"] }
|
||||
handlebars = { version = "4.3.5", features = ["dir_source"] }
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
png = "0.17.6"
|
||||
|
||||
piet-scene = { path = "../piet-scene" }
|
||||
|
|
|
@ -20,7 +20,7 @@ struct Tile {
|
|||
segments: u32,
|
||||
}
|
||||
|
||||
{{> config}}
|
||||
#import config
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<storage> config: Config;
|
||||
|
@ -42,20 +42,20 @@ fn main(
|
|||
let width_in_tiles = config.width_in_tiles;
|
||||
let ix = wg_id.x * width_in_tiles + local_id.x;
|
||||
var backdrop = 0;
|
||||
if local_id.x < width_in_tiles {
|
||||
if (local_id.x < width_in_tiles) {
|
||||
backdrop = tiles[ix].backdrop;
|
||||
}
|
||||
sh_backdrop[local_id.x] = backdrop;
|
||||
// iterate log2(WG_SIZE) times
|
||||
for (var i = 0u; i < firstTrailingBit(WG_SIZE); i += 1u) {
|
||||
workgroupBarrier();
|
||||
if local_id.x >= (1u << i) {
|
||||
if (local_id.x >= (1u << i)) {
|
||||
backdrop += sh_backdrop[local_id.x - (1u << i)];
|
||||
}
|
||||
workgroupBarrier();
|
||||
sh_backdrop[local_id.x] = backdrop;
|
||||
}
|
||||
if local_id.x < width_in_tiles {
|
||||
if (local_id.x < width_in_tiles) {
|
||||
tiles[ix].backdrop = backdrop;
|
||||
}
|
||||
}
|
|
@ -20,8 +20,8 @@ struct Tile {
|
|||
segments: u32,
|
||||
}
|
||||
|
||||
{{> segment}}
|
||||
{{> config}}
|
||||
#import segment
|
||||
#import config
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<storage> config: Config;
|
||||
|
@ -59,7 +59,7 @@ fn main(
|
|||
let y0 = clamp(y, 0.0, 1.0);
|
||||
let y1 = clamp(y + segment.delta.y, 0.0, 1.0);
|
||||
let dy = y0 - y1;
|
||||
if dy != 0.0 {
|
||||
if (dy != 0.0) {
|
||||
let vec_y_recip = 1.0 / segment.delta.y;
|
||||
let t0 = (y0 - y) * vec_y_recip;
|
||||
let t1 = (y1 - y) * vec_y_recip;
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
// Also licensed under MIT license, at your choice.
|
||||
|
||||
{{> pathtag}}
|
||||
#import pathtag
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<storage> path_tags: array<u32>;
|
||||
|
@ -26,18 +26,18 @@ var<storage> tag_monoids: array<TagMonoid>;
|
|||
@group(0) @binding(2)
|
||||
var<storage> path_data: array<u32>;
|
||||
|
||||
{{#if cubics_out}}
|
||||
#ifdef cubics_out
|
||||
@group(0) @binding(3)
|
||||
var<storage, read_write> output: array<vec2<f32>>;
|
||||
{{else}}
|
||||
{{> config}}
|
||||
#else
|
||||
#import config
|
||||
|
||||
struct Tile {
|
||||
backdrop: atomic<i32>,
|
||||
segments: atomic<u32>,
|
||||
}
|
||||
|
||||
{{> segment}}
|
||||
#import segment
|
||||
|
||||
// Should probably be uniform binding
|
||||
@group(0) @binding(3)
|
||||
|
@ -48,7 +48,7 @@ var<storage, read_write> tiles: array<Tile>;
|
|||
|
||||
@group(0) @binding(5)
|
||||
var<storage, read_write> segments: array<Segment>;
|
||||
{{/if}}
|
||||
#endif
|
||||
|
||||
fn read_f32_point(ix: u32) -> vec2<f32> {
|
||||
let x = bitcast<f32>(path_data[ix]);
|
||||
|
@ -63,7 +63,7 @@ fn read_i16_point(ix: u32) -> vec2<f32> {
|
|||
return vec2<f32>(x, y);
|
||||
}
|
||||
|
||||
{{#unless cubics_out}}
|
||||
#ifndef cubics_out
|
||||
let TILE_WIDTH = 16u;
|
||||
let TILE_HEIGHT = 16u;
|
||||
|
||||
|
@ -125,7 +125,7 @@ fn alloc_segment() -> u32 {
|
|||
// TODO: separate small buffer binding for this?
|
||||
return atomicAdd(&tiles[4096].segments, 1u) + 1u;
|
||||
}
|
||||
{{/unless}}
|
||||
#endif
|
||||
|
||||
let MAX_QUADS = 16u;
|
||||
|
||||
|
@ -180,13 +180,13 @@ fn main(
|
|||
p2 = mix(p1, p2, 1.0 / 3.0);
|
||||
p1 = mix(p1, p0, 1.0 / 3.0);
|
||||
}
|
||||
{{#if cubics_out}}
|
||||
#ifdef cubics_out
|
||||
let out_ix = ix * 4u;
|
||||
output[out_ix] = p0;
|
||||
output[out_ix + 1u] = p1;
|
||||
output[out_ix + 2u] = p2;
|
||||
output[out_ix + 3u] = p3;
|
||||
{{else}}
|
||||
#else
|
||||
let err_v = 3.0 * (p2 - p1) + p0 - p3;
|
||||
let err = dot(err_v, err_v);
|
||||
let ACCURACY = 0.25;
|
||||
|
@ -323,6 +323,6 @@ fn main(
|
|||
val_sum += params.val;
|
||||
qp0 = qp2;
|
||||
}
|
||||
{{/if}}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
// Also licensed under MIT license, at your choice.
|
||||
|
||||
{{> pathtag}}
|
||||
#import pathtag
|
||||
|
||||
// Note: should have a single scene binding, path_tags are a slice
|
||||
// in that; need a config uniform.
|
||||
|
@ -50,4 +50,4 @@ fn main(
|
|||
if local_id.x == 0u {
|
||||
reduced[ix >> LG_WG_SIZE] = agg;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
// Also licensed under MIT license, at your choice.
|
||||
|
||||
{{> pathtag}}
|
||||
#import pathtag
|
||||
|
||||
@group(0) @binding(0)
|
||||
var<storage> path_tags: array<u32>;
|
|
@ -27,7 +27,6 @@ use wgpu::{Device, Queue};
|
|||
mod engine;
|
||||
mod render;
|
||||
mod shaders;
|
||||
mod template;
|
||||
mod test_scene;
|
||||
|
||||
async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
|
|
@ -16,13 +16,13 @@
|
|||
|
||||
//! Load rendering shaders.
|
||||
|
||||
use serde_json::json;
|
||||
mod preprocess;
|
||||
|
||||
use std::{collections::HashSet, fs, path::Path};
|
||||
|
||||
use wgpu::Device;
|
||||
|
||||
use crate::{
|
||||
engine::{BindType, Engine, Error, ShaderId},
|
||||
template::ShaderTemplate,
|
||||
};
|
||||
use crate::engine::{BindType, Engine, Error, ShaderId};
|
||||
|
||||
pub const PATHTAG_REDUCE_WG: u32 = 256;
|
||||
pub const PATH_COARSE_WG: u32 = 256;
|
||||
|
@ -36,27 +36,31 @@ pub struct Shaders {
|
|||
}
|
||||
|
||||
pub fn init_shaders(device: &Device, engine: &mut Engine) -> Result<Shaders, Error> {
|
||||
let shaders = ShaderTemplate::new();
|
||||
let shader_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/shader"));
|
||||
let imports = preprocess::get_imports(shader_dir);
|
||||
let read_shader =
|
||||
|path: &str| fs::read_to_string(shader_dir.join(path.to_string() + ".wgsl")).unwrap();
|
||||
let empty = HashSet::new();
|
||||
let pathtag_reduce = engine.add_shader(
|
||||
device,
|
||||
shaders.get_shader("pathtag_reduce", &()).into(),
|
||||
preprocess::preprocess(&read_shader("pathtag_reduce"), &empty, &imports).into(),
|
||||
&[BindType::BufReadOnly, BindType::Buffer],
|
||||
)?;
|
||||
let pathtag_scan = engine.add_shader(
|
||||
device,
|
||||
shaders.get_shader("pathtag_scan", &()).into(),
|
||||
preprocess::preprocess(&read_shader("pathtag_scan"), &empty, &imports).into(),
|
||||
&[
|
||||
BindType::BufReadOnly,
|
||||
BindType::BufReadOnly,
|
||||
BindType::Buffer,
|
||||
],
|
||||
)?;
|
||||
let path_coarse_config = json!({"cubics_out": false});
|
||||
let path_coarse_config = HashSet::new();
|
||||
// path_coarse_config.add("cubics_out");
|
||||
|
||||
let path_coarse = engine.add_shader(
|
||||
device,
|
||||
shaders
|
||||
.get_shader("path_coarse", &path_coarse_config)
|
||||
.into(),
|
||||
preprocess::preprocess(&read_shader("path_coarse"), &path_coarse_config, &imports).into(),
|
||||
&[
|
||||
BindType::BufReadOnly,
|
||||
BindType::BufReadOnly,
|
||||
|
@ -68,12 +72,12 @@ pub fn init_shaders(device: &Device, engine: &mut Engine) -> Result<Shaders, Err
|
|||
)?;
|
||||
let backdrop = engine.add_shader(
|
||||
device,
|
||||
shaders.get_shader("backdrop", &()).into(),
|
||||
preprocess::preprocess(&read_shader("backdrop"), &empty, &imports).into(),
|
||||
&[BindType::BufReadOnly, BindType::Buffer],
|
||||
)?;
|
||||
let fine = engine.add_shader(
|
||||
device,
|
||||
shaders.get_shader("fine", &()).into(),
|
||||
preprocess::preprocess(&read_shader("fine"), &empty, &imports).into(),
|
||||
&[
|
||||
BindType::BufReadOnly,
|
||||
BindType::BufReadOnly,
|
||||
|
|
100
piet-wgsl/src/shaders/preprocess.rs
Normal file
100
piet-wgsl/src/shaders/preprocess.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fs,
|
||||
path::Path,
|
||||
vec,
|
||||
};
|
||||
|
||||
pub fn get_imports(shader_dir: &Path) -> HashMap<String, String> {
|
||||
let mut imports = HashMap::new();
|
||||
let imports_dir = shader_dir.join("shared");
|
||||
for entry in imports_dir
|
||||
.read_dir()
|
||||
.expect("Can read shader import directory")
|
||||
{
|
||||
let entry = entry.expect("Can continue reading shader import directory");
|
||||
if entry.file_type().unwrap().is_file() {
|
||||
let file_name = entry.file_name();
|
||||
if let Some(name) = file_name.to_str() {
|
||||
let suffix = ".wgsl";
|
||||
if name.ends_with(suffix) {
|
||||
let import_name = name[..(name.len() - suffix.len())].to_owned();
|
||||
let contents = fs::read_to_string(imports_dir.join(file_name))
|
||||
.expect("Could read shader {import_name} contents");
|
||||
imports.insert(import_name, contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
imports
|
||||
}
|
||||
|
||||
pub struct StackItem {
|
||||
active: bool,
|
||||
else_passed: bool,
|
||||
}
|
||||
|
||||
pub fn preprocess(
|
||||
input: &str,
|
||||
defines: &HashSet<String>,
|
||||
imports: &HashMap<String, String>,
|
||||
) -> String {
|
||||
let mut output = String::with_capacity(input.len());
|
||||
let mut stack = vec![];
|
||||
|
||||
for (line_number, line) in input.lines().enumerate() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.starts_with("#") {
|
||||
let trimmed = &trimmed[1..];
|
||||
let val_idx = trimmed
|
||||
.chars()
|
||||
.take_while(|char| char.is_alphanumeric())
|
||||
.map(char::len_utf8)
|
||||
.sum();
|
||||
let arg = trimmed[val_idx..].trim();
|
||||
match &trimmed[..val_idx] {
|
||||
x @ ("ifdef" | "ifndef") => {
|
||||
let exists = defines.contains(arg);
|
||||
let mode = x == "ifdef";
|
||||
stack.push(StackItem {
|
||||
active: mode == exists,
|
||||
else_passed: false,
|
||||
});
|
||||
}
|
||||
"else" => {
|
||||
let item = stack.last_mut();
|
||||
if let Some(item) = item {
|
||||
if item.else_passed {
|
||||
eprintln!("Second else for same ifdef/ifndef (line {line_number}); ignoring second else")
|
||||
} else {
|
||||
item.else_passed = true;
|
||||
item.active = !item.active;
|
||||
}
|
||||
}
|
||||
}
|
||||
"endif" => {
|
||||
if let None = stack.pop() {
|
||||
eprintln!("Mismatched endif (line {line_number})");
|
||||
}
|
||||
}
|
||||
"import" => {
|
||||
let import = imports.get(arg);
|
||||
if let Some(import) = import {
|
||||
output.push_str(&preprocess(import, defines, imports));
|
||||
} else {
|
||||
eprintln!("Unkown import `{arg}` (line {line_number})");
|
||||
}
|
||||
}
|
||||
val => {
|
||||
eprintln!("Unknown preprocessor directive `{val}` (line {line_number})")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if stack.last().map(|x| x.active).unwrap_or(true) {
|
||||
output.push_str(line);
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Also licensed under MIT license, at your choice.
|
||||
|
||||
use handlebars::Handlebars;
|
||||
use serde::Serialize;
|
||||
|
||||
pub struct ShaderTemplate {
|
||||
handlebars: Handlebars<'static>,
|
||||
}
|
||||
|
||||
impl ShaderTemplate {
|
||||
pub fn new() -> ShaderTemplate {
|
||||
let mut handlebars = Handlebars::new();
|
||||
handlebars
|
||||
.register_templates_directory("twgsl", concat!(env!("CARGO_MANIFEST_DIR"), "/shader"))
|
||||
.unwrap();
|
||||
handlebars.register_escape_fn(handlebars::no_escape);
|
||||
ShaderTemplate { handlebars }
|
||||
}
|
||||
|
||||
pub fn get_shader(&self, shader_name: &str, data: &impl Serialize) -> String {
|
||||
self.handlebars.render(shader_name, data).unwrap()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue