From e2ed54361de33850991a266dc376dbf0eccca9a0 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Mon, 4 May 2020 17:05:54 +0200 Subject: [PATCH] Fix rebase issues and split into library and cli/winit binaries --- Cargo.lock | 688 ++++++++++++++++++++++++++++++++++- piet-gpu/Cargo.toml | 50 +-- piet-gpu/bin/cli.rs | 89 +++++ piet-gpu/bin/winit.rs | 122 +++++++ piet-gpu/shader/kernel4.comp | 2 +- piet-gpu/shader/kernel4.spv | Bin 20832 -> 20180 bytes piet-gpu/src/lib.rs | 321 ++++++++++++++++ piet-gpu/src/main.rs | 461 ----------------------- 8 files changed, 1242 insertions(+), 491 deletions(-) create mode 100644 piet-gpu/bin/cli.rs create mode 100644 piet-gpu/bin/winit.rs create mode 100644 piet-gpu/src/lib.rs delete mode 100644 piet-gpu/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index af141b5..a3e7735 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,35 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +[[package]] +name = "andrew" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +dependencies = [ + "bitflags", + "line_drawing", + "rusttype 0.7.9", + "walkdir", + "xdg", + "xml-rs", +] + +[[package]] +name = "android_glue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits", +] + [[package]] name = "arrayvec" version = "0.5.1" @@ -21,18 +50,50 @@ dependencies = [ "libloading", ] +[[package]] +name = "ash-window" +version = "0.3.0" +source = "git+https://github.com/norse-rs/ash-window.git?branch=dyn_trait#ff8cd779b339067f00e808add1203f6c0d074ba5" +dependencies = [ + "ash", + "raw-window-handle", +] + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "calloop" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" +dependencies = [ + "mio", + "mio-extras", + "nix", +] + [[package]] name = "cc" version = "1.0.50" @@ -45,6 +106,71 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "cocoa" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + +[[package]] +name = "core-graphics" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc065219542086f72d1e9f7aadbbab0989e980263695d129d502082d063a9d0" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "core-graphics", + "libc", + "objc", +] + [[package]] name = "crc32fast" version = "1.2.0" @@ -64,6 +190,58 @@ dependencies = [ "byteorder", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "getrandom" version = "0.1.14" @@ -90,6 +268,31 @@ dependencies = [ "adler32", ] +[[package]] +name = "instant" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7152d2aed88aa566e7a342250f21ba2222c1ae230ad577499dbfa3c18475b80" + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "kurbo" version = "0.5.11" @@ -98,6 +301,18 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" + [[package]] name = "libc" version = "0.2.69" @@ -111,7 +326,144 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ "cc", - "winapi", + "winapi 0.3.8", +] + +[[package]] +name = "line_drawing" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +dependencies = [ + "num-traits", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "mio" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", ] [[package]] @@ -120,6 +472,45 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +[[package]] +name = "ordered-float" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.8", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + [[package]] name = "piet" version = "0.0.12" @@ -140,14 +531,15 @@ dependencies = [ "png", "rand", "roxmltree", + "winit", ] [[package]] name = "piet-gpu-derive" version = "0.0.0" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.10", + "quote 1.0.3", "syn", ] @@ -156,7 +548,9 @@ name = "piet-gpu-hal" version = "0.1.0" dependencies = [ "ash", + "ash-window", "once_cell", + "raw-window-handle", ] [[package]] @@ -167,6 +561,12 @@ dependencies = [ "piet-gpu-derive", ] +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" + [[package]] name = "png" version = "0.16.2" @@ -185,13 +585,31 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + [[package]] name = "proc-macro2" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.0", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", ] [[package]] @@ -200,7 +618,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.10", ] [[package]] @@ -244,6 +662,21 @@ dependencies = [ "rand_core", ] +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + [[package]] name = "roxmltree" version = "0.11.0" @@ -253,29 +686,190 @@ dependencies = [ "xmlparser", ] +[[package]] +name = "rusttype" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +dependencies = [ + "rusttype 0.8.3", +] + +[[package]] +name = "rusttype" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +dependencies = [ + "approx", + "ordered-float", + "stb_truetype", +] + +[[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 = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" + +[[package]] +name = "smithay-client-toolkit" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" +dependencies = [ + "andrew", + "bitflags", + "dlib", + "lazy_static", + "memmap", + "nix", + "wayland-client", + "wayland-protocols", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder", +] + [[package]] name = "syn" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2 1.0.10", + "quote 1.0.3", + "unicode-xid 0.2.0", ] +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi 0.3.8", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wayland-client" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" +dependencies = [ + "bitflags", + "calloop", + "downcast-rs", + "libc", + "mio", + "nix", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" +dependencies = [ + "nix", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +dependencies = [ + "dlib", + "lazy_static", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.8" @@ -286,18 +880,96 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.8", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winit" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc53342d3d1a3d57f3949e0692d93d5a8adb7814d8683cef4a09c2b550e94246" +dependencies = [ + "android_glue", + "bitflags", + "cocoa", + "core-foundation", + "core-graphics", + "core-video-sys", + "dispatch", + "instant", + "lazy_static", + "libc", + "log", + "mio", + "mio-extras", + "objc", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "smithay-client-toolkit", + "wayland-client", + "winapi 0.3.8", + "x11-dl", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +dependencies = [ + "lazy_static", + "libc", + "maybe-uninit", + "pkg-config", +] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "xml-rs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" + [[package]] name = "xmlparser" version = "0.13.1" diff --git a/piet-gpu/Cargo.toml b/piet-gpu/Cargo.toml index d4522f0..a922a46 100644 --- a/piet-gpu/Cargo.toml +++ b/piet-gpu/Cargo.toml @@ -1,21 +1,29 @@ -[package] -name = "piet-gpu" -version = "0.1.0" -authors = ["Raph Levien "] -description = "A compute-centric GPU 2D renderer." -license = "MIT/Apache-2.0" -edition = "2018" - -[dependencies.piet-gpu-hal] -path = "../piet-gpu-hal" - -[dependencies.piet-gpu-types] -path = "../piet-gpu-types" - -[dependencies] -kurbo = "0.5.11" -piet = "0.0.12" -png = "0.16.2" -rand = "0.7.3" -roxmltree = "0.11" -winit = "0.22" \ No newline at end of file +[package] +name = "piet-gpu" +version = "0.1.0" +authors = ["Raph Levien "] +description = "A compute-centric GPU 2D renderer." +license = "MIT/Apache-2.0" +edition = "2018" + +[[bin]] +name = "cli" +path = "bin/cli.rs" + +[[bin]] +name = "winit" +path = "bin/winit.rs" + +[dependencies.piet-gpu-hal] +path = "../piet-gpu-hal" + +[dependencies.piet-gpu-types] +path = "../piet-gpu-types" + +[dependencies] +kurbo = "0.5.11" +piet = "0.0.12" +png = "0.16.2" +rand = "0.7.3" +roxmltree = "0.11" +winit = "0.22" diff --git a/piet-gpu/bin/cli.rs b/piet-gpu/bin/cli.rs new file mode 100644 index 0000000..1a3c37a --- /dev/null +++ b/piet-gpu/bin/cli.rs @@ -0,0 +1,89 @@ +use std::fs::File; +use std::io::BufWriter; +use std::path::Path; + + +use piet::Color; + +use piet_gpu_hal::vulkan::VkInstance; +use piet_gpu_hal::{CmdBuf, Device, Error, MemFlags}; + +use piet_gpu::{PietGpuRenderContext, Renderer, render_scene, WIDTH, HEIGHT}; + +#[allow(unused)] +fn dump_scene(buf: &[u8]) { + for i in 0..(buf.len() / 4) { + let mut buf_u32 = [0u8; 4]; + buf_u32.copy_from_slice(&buf[i * 4..i * 4 + 4]); + println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32)); + } +} + +fn main() -> Result<(), Error> { + let (instance, _) = VkInstance::new(None)?; + unsafe { + let device = instance.device(None)?; + + let fence = device.create_fence(false)?; + let mut cmd_buf = device.create_cmd_buf()?; + let query_pool = device.create_query_pool(6)?; + + let mut ctx = PietGpuRenderContext::new(); + render_scene(&mut ctx); + let scene = ctx.get_scene_buf(); + //dump_scene(&scene); + + let renderer = Renderer::new(&device, scene)?; + let image_buf = device.create_buffer((WIDTH * HEIGHT * 4) as u64, MemFlags::host_coherent())?; + + cmd_buf.begin(); + renderer.record(&mut cmd_buf, &query_pool); + cmd_buf.copy_image_to_buffer(&renderer.image_dev, &image_buf); + cmd_buf.finish(); + device.run_cmd_buf(&cmd_buf, &[], &[], Some(&fence))?; + device.wait_and_reset(&[fence])?; + let timestamps = device.reap_query_pool(&query_pool).unwrap(); + println!("Kernel 1 time: {:.3}ms", timestamps[0] * 1e3); + println!( + "Kernel 2s time: {:.3}ms", + (timestamps[1] - timestamps[0]) * 1e3 + ); + println!( + "Kernel 2f time: {:.3}ms", + (timestamps[2] - timestamps[1]) * 1e3 + ); + println!( + "Kernel 3 time: {:.3}ms", + (timestamps[3] - timestamps[2]) * 1e3 + ); + println!( + "Render time: {:.3}ms", + (timestamps[4] - timestamps[3]) * 1e3 + ); + + /* + let mut k1_data: Vec = Default::default(); + device.read_buffer(&segment_buf, &mut k1_data).unwrap(); + dump_k1_data(&k1_data); + */ + + let mut img_data: Vec = Default::default(); + // Note: because png can use a `&[u8]` slice, we could avoid an extra copy + // (probably passing a slice into a closure). But for now: keep it simple. + device.read_buffer(&image_buf, &mut img_data).unwrap(); + + // Write image as PNG file. + let path = Path::new("image.png"); + let file = File::create(path).unwrap(); + let ref mut w = BufWriter::new(file); + + let mut encoder = png::Encoder::new(w, WIDTH as u32, HEIGHT as u32); + encoder.set_color(png::ColorType::RGBA); + encoder.set_depth(png::BitDepth::Eight); + let mut writer = encoder.write_header().unwrap(); + + writer.write_image_data(&img_data).unwrap(); + } + + Ok(()) +} diff --git a/piet-gpu/bin/winit.rs b/piet-gpu/bin/winit.rs new file mode 100644 index 0000000..e5f174a --- /dev/null +++ b/piet-gpu/bin/winit.rs @@ -0,0 +1,122 @@ +use piet_gpu_hal::vulkan::VkInstance; +use piet_gpu_hal::{CmdBuf, Device, Error, ImageLayout}; + +use piet_gpu::{PietGpuRenderContext, Renderer, render_scene, WIDTH, HEIGHT}; + +use winit::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; + +const NUM_FRAMES: usize = 2; + +fn main() -> Result<(), Error> { + let event_loop = EventLoop::new(); + let window = WindowBuilder::new() + .with_inner_size(winit::dpi::LogicalSize { + width: (WIDTH / 2) as f64, + height: (HEIGHT / 2) as f64, + }) + .with_resizable(false) // currently not supported + .build(&event_loop)?; + + let (instance, surface) = VkInstance::new(Some(&window))?; + unsafe { + let device = instance.device(surface.as_ref())?; + let mut swapchain = instance.swapchain(&device, surface.as_ref().unwrap())?; + + let mut current_frame = 0; + let present_semaphores = (0..NUM_FRAMES) + .map(|_| device.create_semaphore()) + .collect::, Error>>()?; + let frame_fences = (0..NUM_FRAMES) + .map(|_| device.create_fence(false)) + .collect::, Error>>()?; + let mut cmd_buffers = (0..NUM_FRAMES) + .map(|_| device.create_cmd_buf()) + .collect::, Error>>()?; + let query_pools = (0..NUM_FRAMES) + .map(|_| device.create_query_pool(6)) + .collect::, Error>>()?; + + let mut ctx = PietGpuRenderContext::new(); + render_scene(&mut ctx); + let scene = ctx.get_scene_buf(); + + let renderer = Renderer::new(&device, scene)?; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Poll; // `ControlFlow::Wait` if only re-render on event + + match event { + Event::WindowEvent { event, window_id } if window_id == window.id() => { + match event { + WindowEvent::CloseRequested => { + *control_flow = ControlFlow::Exit; + } + _ => (), + } + } + Event::MainEventsCleared => { + window.request_redraw(); + } + Event::RedrawRequested(window_id) if window_id == window.id() => { + let frame_idx = current_frame % NUM_FRAMES; + let query_pool = &query_pools[frame_idx]; + + if current_frame >= NUM_FRAMES { + device.wait_and_reset(&[frame_fences[frame_idx]]).unwrap(); + + let timestamps = device.reap_query_pool(query_pool).unwrap(); + window.set_title(&format!("k1: {:.3}ms, k2s: {:.3}ms, k2f: {:.3}ms, k3: {:.3}ms, k4: {:.3}ms", + timestamps[0] * 1e3, + (timestamps[1] - timestamps[0]) * 1e3, + (timestamps[2] - timestamps[1]) * 1e3, + (timestamps[3] - timestamps[2]) * 1e3, + (timestamps[4] - timestamps[3]) * 1e3, + )); + } + + let (image_idx, acquisition_semaphore) = swapchain.next().unwrap(); + let swap_image = swapchain.image(image_idx); + let cmd_buf = &mut cmd_buffers[frame_idx]; + cmd_buf.begin(); + cmd_buf.reset_query_pool(&query_pool); + + renderer.record(cmd_buf, &query_pool); + + // Image -> Swapchain + cmd_buf.image_barrier( + &swap_image, + ImageLayout::Undefined, + ImageLayout::BlitDst, + ); + cmd_buf.blit_image(&renderer.image_dev, &swap_image); + cmd_buf.image_barrier( + &swap_image, + ImageLayout::BlitDst, + ImageLayout::Present, + ); + cmd_buf.finish(); + + device + .run_cmd_buf( + &cmd_buf, + &[acquisition_semaphore], + &[present_semaphores[frame_idx]], + Some(&frame_fences[frame_idx]), + ) + .unwrap(); + + swapchain + .present(image_idx, &[present_semaphores[frame_idx]]) + .unwrap(); + + current_frame += 1; + } + _ => (), + } + }) + } +} diff --git a/piet-gpu/shader/kernel4.comp b/piet-gpu/shader/kernel4.comp index f152caf..2a0b7f7 100644 --- a/piet-gpu/shader/kernel4.comp +++ b/piet-gpu/shader/kernel4.comp @@ -24,7 +24,7 @@ layout(set = 0, binding = 2) buffer FillSegBuf { uint[] fill_seg; }; -layout(rgba8, set = 0, binding = 2) uniform writeonly image2D image; +layout(rgba8, set = 0, binding = 3) uniform writeonly image2D image; #include "ptcl.h" #include "segment.h" diff --git a/piet-gpu/shader/kernel4.spv b/piet-gpu/shader/kernel4.spv index db03dde9d380f2d582c27e18efbf8572d37160a0..d9dacc030717276f28521e14fcdae50bd590458b 100644 GIT binary patch delta 398 zcmYk2y-EX75QXRNPhyaSG+|xSBwDJi1SG`&)g*#>1Q8J-);2;4t2~5_tyqL>X(_&d zimi{5?F;;1bx8ixD6qvcbA54?=r)axFVWf&LC1l__%7B^v+$ delta 1038 zcmYk5O>5Lp6ozjaXRKhWE89U7b(XpnMDb%S!?d>5XVU&CA{aAPWN*X$8 z2wNe92KPMi=3uF}xY5hj`pYGI0GnIy4f<10RwxTisLX39XK#cwEXs=E_(amZPuN6l zW6jpe+i0&D%C+#s3{@UIRA&C`gXoxFE#B>V+sr2@Jq?T22heBGJW|OIqjzZOxsXq* zTSN=!QTC|speND$_<`8!eqviv>-&&>gc{k2zxsIDr%)rCSR$!&)I;=c&=Im9k`PwW zvSIOMPdjbtW4}(^p4A!qeDSNbwKxCDi78Uw*}F{5N0~;;ydpbWG0Oh2a}~3@11z^Ug(uq-QNb7h-P<*Wxh4h>>ja(=A4S(jVu~JBL2)6>rdQ+$zN6vml4Z+ zi9FZO=wcb+!TLD+F!}T9;0m#a<#FT#Vw>nN%uReA6Z=*9aawPavO)3t=#R-i{XJfq diff --git a/piet-gpu/src/lib.rs b/piet-gpu/src/lib.rs new file mode 100644 index 0000000..2adbfc1 --- /dev/null +++ b/piet-gpu/src/lib.rs @@ -0,0 +1,321 @@ +mod render_ctx; +mod pico_svg; + +pub use render_ctx::PietGpuRenderContext; + +use rand::{Rng, RngCore}; + +use piet::kurbo::{BezPath, Circle, Line, Point, Vec2}; +use piet::{Color, RenderContext}; + +use piet_gpu_hal::vulkan::VkInstance; +use piet_gpu_hal::{CmdBuf, Device, Error, ImageLayout, MemFlags}; + +use pico_svg::PicoSvg; + +pub const WIDTH: usize = TILE_W * WIDTH_IN_TILES; +pub const HEIGHT: usize = TILE_H * HEIGHT_IN_TILES; + +const TILE_W: usize = 16; +const TILE_H: usize = 16; + +const WIDTH_IN_TILEGROUPS: usize = 4; +const HEIGHT_IN_TILEGROUPS: usize = 96; +const TILEGROUP_STRIDE: usize = 2048; + +const WIDTH_IN_TILES: usize = 128; +const HEIGHT_IN_TILES: usize = 96; +const PTCL_INITIAL_ALLOC: usize = 1024; + +const K2_PER_TILE_SIZE: usize = 8; + +const N_CIRCLES: usize = 1; + +pub fn render_scene(rc: &mut impl RenderContext) { + let mut rng = rand::thread_rng(); + for _ in 0..N_CIRCLES { + let color = Color::from_rgba32_u32(rng.next_u32()); + let center = Point::new( + rng.gen_range(0.0, WIDTH as f64), + rng.gen_range(0.0, HEIGHT as f64), + ); + let radius = rng.gen_range(0.0, 50.0); + let circle = Circle::new(center, radius); + rc.fill(circle, &color); + } + let mut path = BezPath::new(); + path.move_to((100.0, 1150.0)); + path.line_to((200.0, 1200.0)); + path.line_to((150.0, 1250.0)); + path.close_path(); + rc.fill(path, &Color::rgb8(128, 0, 128)); + rc.stroke( + Line::new((100.0, 100.0), (200.0, 150.0)), + &Color::WHITE, + 5.0, + ); + //render_cardioid(rc); + render_tiger(rc); +} + +#[allow(unused)] +fn render_cardioid(rc: &mut impl RenderContext) { + let n = 91; + let dth = std::f64::consts::PI * 2.0 / (n as f64); + let center = Point::new(1024.0, 768.0); + let r = 750.0; + let mut path = BezPath::new(); + for i in 1..n { + let p0 = center + Vec2::from_angle(i as f64 * dth) * r; + let p1 = center + Vec2::from_angle(((i * 2) % n) as f64 * dth) * r; + rc.fill(&Circle::new(p0, 8.0), &Color::WHITE); + path.move_to(p0); + path.line_to(p1); + //rc.stroke(Line::new(p0, p1), &Color::BLACK, 2.0); + } + rc.stroke(&path, &Color::BLACK, 2.0); +} + +fn render_tiger(rc: &mut impl RenderContext) { + let xml_str = std::str::from_utf8(include_bytes!("../Ghostscript_Tiger.svg")).unwrap(); + let start = std::time::Instant::now(); + let svg = PicoSvg::load(xml_str, 8.0).unwrap(); + println!("parsing time: {:?}", start.elapsed()); + + let start = std::time::Instant::now(); + svg.render(rc); + println!("flattening and encoding time: {:?}", start.elapsed()); +} + +#[allow(unused)] +fn dump_scene(buf: &[u8]) { + for i in 0..(buf.len() / 4) { + let mut buf_u32 = [0u8; 4]; + buf_u32.copy_from_slice(&buf[i * 4..i * 4 + 4]); + println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32)); + } +} + +#[allow(unused)] +fn dump_k1_data(k1_buf: &[u32]) { + for i in 0..k1_buf.len() { + if k1_buf[i] != 0 { + println!("{:4x}: {:8x}", i, k1_buf[i]); + } + } +} + +pub struct Renderer { + pub image_dev: D::Image, // resulting image + + scene_buf: D::Buffer, + scene_dev: D::Buffer, + + k1_alloc_buf_host: D::Buffer, + k1_alloc_buf_dev: D::Buffer, + k2s_alloc_buf_host: D::Buffer, + k2s_alloc_buf_dev: D::Buffer, + k2f_alloc_buf_host: D::Buffer, + k2f_alloc_buf_dev: D::Buffer, + k3_alloc_buf_host: D::Buffer, + k3_alloc_buf_dev: D::Buffer, + tilegroup_buf: D::Buffer, + ptcl_buf: D::Buffer, + + k1_pipeline: D::Pipeline, + k1_ds: D::DescriptorSet, + k2s_pipeline: D::Pipeline, + k2s_ds: D::DescriptorSet, + k2f_pipeline: D::Pipeline, + k2f_ds: D::DescriptorSet, + k3_pipeline: D::Pipeline, + k3_ds: D::DescriptorSet, + k4_pipeline: D::Pipeline, + k4_ds: D::DescriptorSet, +} + +impl Renderer { + pub unsafe fn new(device: &D, scene: &[u8]) -> Result { + let host = MemFlags::host_coherent(); + let dev = MemFlags::device_local(); + + let scene_buf = device + .create_buffer(std::mem::size_of_val(&scene[..]) as u64, host) + .unwrap(); + let scene_dev = device + .create_buffer(std::mem::size_of_val(&scene[..]) as u64, dev) + .unwrap(); + device.write_buffer(&scene_buf, &scene)?; + + let tilegroup_buf = device.create_buffer(4 * 1024 * 1024, dev)?; + let ptcl_buf = device.create_buffer(48 * 1024 * 1024, dev)?; + let segment_buf = device.create_buffer(64 * 1024 * 1024, dev)?; + let fill_seg_buf = device.create_buffer(64 * 1024 * 1024, dev)?; + let image_dev = device.create_image2d(WIDTH as u32, HEIGHT as u32, dev)?; + + let k1_alloc_buf_host = device.create_buffer(4, host)?; + let k1_alloc_buf_dev = device.create_buffer(4, dev)?; + let k1_alloc_start = WIDTH_IN_TILEGROUPS * HEIGHT_IN_TILEGROUPS * TILEGROUP_STRIDE; + device.write_buffer(&k1_alloc_buf_host, &[k1_alloc_start as u32])?; + let k1_code = include_bytes!("../shader/kernel1.spv"); + let k1_pipeline = device + .create_simple_compute_pipeline(k1_code, 3, 0)?; + let k1_ds = device + .create_descriptor_set( + &k1_pipeline, + &[&scene_dev, &tilegroup_buf, &k1_alloc_buf_dev], + &[], + )?; + + let k2s_alloc_buf_host = device.create_buffer(4, host)?; + let k2s_alloc_buf_dev = device.create_buffer(4, dev)?; + let k2s_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * K2_PER_TILE_SIZE; + device + .write_buffer(&k2s_alloc_buf_host, &[k2s_alloc_start as u32]) + ?; + let k2s_code = include_bytes!("../shader/kernel2s.spv"); + let k2s_pipeline = device + .create_simple_compute_pipeline(k2s_code, 4, 0) + ?; + let k2s_ds = device + .create_descriptor_set( + &k2s_pipeline, + &[&scene_dev, &tilegroup_buf, &segment_buf, &k2s_alloc_buf_dev], + &[], + ) + ?; + + let k2f_alloc_buf_host = device.create_buffer(4, host)?; + let k2f_alloc_buf_dev = device.create_buffer(4, dev)?; + let k2f_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * K2_PER_TILE_SIZE; + device + .write_buffer(&k2f_alloc_buf_host, &[k2f_alloc_start as u32]) + ?; + let k2f_code = include_bytes!("../shader/kernel2f.spv"); + let k2f_pipeline = device.create_simple_compute_pipeline(k2f_code, 4, 0)?; + let k2f_ds = device + .create_descriptor_set( + &k2f_pipeline, + &[ + &scene_dev, + &tilegroup_buf, + &fill_seg_buf, + &k2f_alloc_buf_dev, + ], + &[], + ) + ?; + + let k3_alloc_buf_host = device.create_buffer(4, host)?; + let k3_alloc_buf_dev = device.create_buffer(4, dev)?; + let k3_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * PTCL_INITIAL_ALLOC; + device + .write_buffer(&k3_alloc_buf_host, &[k3_alloc_start as u32]) + ?; + let k3_code = include_bytes!("../shader/kernel3.spv"); + let k3_pipeline = device.create_simple_compute_pipeline(k3_code, 6, 0)?; + let k3_ds = device + .create_descriptor_set( + &k3_pipeline, + &[ + &scene_dev, + &tilegroup_buf, + &segment_buf, + &fill_seg_buf, + &ptcl_buf, + &k3_alloc_buf_dev, + ], + &[], + ) + ?; + + let k4_code = include_bytes!("../shader/kernel4.spv"); + let k4_pipeline = device.create_simple_compute_pipeline(k4_code, 3, 1)?; + let k4_ds = device + .create_descriptor_set(&k4_pipeline, &[&ptcl_buf, &segment_buf, &fill_seg_buf], &[&image_dev]) + ?; + + Ok(Renderer { + scene_buf, + scene_dev, + image_dev, + k1_alloc_buf_host, + k1_alloc_buf_dev, + k2s_alloc_buf_host, + k2s_alloc_buf_dev, + k2f_alloc_buf_host, + k2f_alloc_buf_dev, + k3_alloc_buf_host, + k3_alloc_buf_dev, + tilegroup_buf, + ptcl_buf, + k1_pipeline, + k1_ds, + k2s_pipeline, + k2s_ds, + k2f_pipeline, + k2f_ds, + k3_pipeline, + k3_ds, + k4_pipeline, + k4_ds, + }) + } + + pub unsafe fn record(&self, cmd_buf: &mut impl CmdBuf, query_pool: &D::QueryPool) { + cmd_buf.copy_buffer(&self.scene_buf, &self.scene_dev); + // Note: we could use one alloc buf and reuse it. But we'll stick with + // multiple ones for clarity. + cmd_buf.copy_buffer(&self.k1_alloc_buf_host, &self.k1_alloc_buf_dev); + cmd_buf.copy_buffer(&self.k2s_alloc_buf_host, &self.k2s_alloc_buf_dev); + cmd_buf.copy_buffer(&self.k2f_alloc_buf_host, &self.k2f_alloc_buf_dev); + cmd_buf.copy_buffer(&self.k3_alloc_buf_host, &self.k3_alloc_buf_dev); + // Note: these clears aren't necessary, and are here to make inspection + // of the buffers cleaner. Can likely be removed. + cmd_buf.clear_buffer(&self.tilegroup_buf); + cmd_buf.clear_buffer(&self.ptcl_buf); + cmd_buf.memory_barrier(); + cmd_buf.image_barrier(&self.image_dev, ImageLayout::Undefined, ImageLayout::General); + cmd_buf.reset_query_pool(&query_pool); + cmd_buf.write_timestamp(&query_pool, 0); + cmd_buf.dispatch( + &self.k1_pipeline, + &self.k1_ds, + ((WIDTH / 512) as u32, (HEIGHT / 512) as u32, 1), + ); + cmd_buf.write_timestamp(&query_pool, 1); + cmd_buf.memory_barrier(); + cmd_buf.dispatch( + &self.k2s_pipeline, + &self.k2s_ds, + ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 1), + ); + cmd_buf.write_timestamp(&query_pool, 2); + // Note: this barrier is not necessary (k2f does not depend on + // k2s output), but I'm keeping it here to increase transparency + // of performance. + cmd_buf.memory_barrier(); + cmd_buf.dispatch( + &self.k2f_pipeline, + &self.k2f_ds, + ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 2), + ); + cmd_buf.write_timestamp(&query_pool, 3); + cmd_buf.memory_barrier(); + cmd_buf.dispatch( + &self.k3_pipeline, + &self.k3_ds, + ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 3), + ); + cmd_buf.write_timestamp(&query_pool, 4); + cmd_buf.memory_barrier(); + cmd_buf.dispatch( + &self.k4_pipeline, + &self.k4_ds, + ((WIDTH / TILE_W) as u32, (HEIGHT / TILE_H) as u32, 1), + ); + cmd_buf.write_timestamp(&query_pool, 5); + cmd_buf.memory_barrier(); + cmd_buf.image_barrier(&self.image_dev, ImageLayout::General, ImageLayout::BlitSrc); + } +} diff --git a/piet-gpu/src/main.rs b/piet-gpu/src/main.rs deleted file mode 100644 index 0b7a6fe..0000000 --- a/piet-gpu/src/main.rs +++ /dev/null @@ -1,461 +0,0 @@ -use std::fs::File; -use std::io::BufWriter; -use std::path::Path; - -use rand::{Rng, RngCore}; - -use piet::kurbo::{BezPath, Circle, Line, Point, Vec2}; -use piet::{Color, RenderContext}; - -use piet_gpu_hal::vulkan::VkInstance; -use piet_gpu_hal::{CmdBuf, Device, Error, ImageLayout, MemFlags}; - -mod pico_svg; -mod render_ctx; - -use render_ctx::PietGpuRenderContext; -use pico_svg::PicoSvg; - -use winit::{ - event::{Event, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, - window::WindowBuilder, -}; - -const WIDTH: usize = TILE_W * WIDTH_IN_TILES; -const HEIGHT: usize = TILE_H * HEIGHT_IN_TILES; - -const TILE_W: usize = 16; -const TILE_H: usize = 16; - -const WIDTH_IN_TILEGROUPS: usize = 4; -const HEIGHT_IN_TILEGROUPS: usize = 96; -const TILEGROUP_STRIDE: usize = 2048; - -const WIDTH_IN_TILES: usize = 128; -const HEIGHT_IN_TILES: usize = 96; -const PTCL_INITIAL_ALLOC: usize = 1024; - -const K2_PER_TILE_SIZE: usize = 8; - -const N_CIRCLES: usize = 1; - -const NUM_FRAMES: usize = 2; - -fn render_scene(rc: &mut impl RenderContext) { - let mut rng = rand::thread_rng(); - for _ in 0..N_CIRCLES { - let color = Color::from_rgba32_u32(rng.next_u32()); - let center = Point::new( - rng.gen_range(0.0, WIDTH as f64), - rng.gen_range(0.0, HEIGHT as f64), - ); - let radius = rng.gen_range(0.0, 50.0); - let circle = Circle::new(center, radius); - rc.fill(circle, &color); - } - let mut path = BezPath::new(); - path.move_to((100.0, 1150.0)); - path.line_to((200.0, 1200.0)); - path.line_to((150.0, 1250.0)); - path.close_path(); - rc.fill(path, &Color::rgb8(128, 0, 128)); - rc.stroke( - Line::new((100.0, 100.0), (200.0, 150.0)), - &Color::WHITE, - 5.0, - ); - //render_cardioid(rc); - render_tiger(rc); -} - -#[allow(unused)] -fn render_cardioid(rc: &mut impl RenderContext) { - let n = 91; - let dth = std::f64::consts::PI * 2.0 / (n as f64); - let center = Point::new(1024.0, 768.0); - let r = 750.0; - let mut path = BezPath::new(); - for i in 1..n { - let p0 = center + Vec2::from_angle(i as f64 * dth) * r; - let p1 = center + Vec2::from_angle(((i * 2) % n) as f64 * dth) * r; - rc.fill(&Circle::new(p0, 8.0), &Color::WHITE); - path.move_to(p0); - path.line_to(p1); - //rc.stroke(Line::new(p0, p1), &Color::BLACK, 2.0); - } - rc.stroke(&path, &Color::BLACK, 2.0); -} - -fn render_tiger(rc: &mut impl RenderContext) { - let xml_str = std::str::from_utf8(include_bytes!("../Ghostscript_Tiger.svg")).unwrap(); - let start = std::time::Instant::now(); - let svg = PicoSvg::load(xml_str, 8.0).unwrap(); - println!("parsing time: {:?}", start.elapsed()); - - let start = std::time::Instant::now(); - svg.render(rc); - println!("flattening and encoding time: {:?}", start.elapsed()); -} - -#[allow(unused)] -fn dump_scene(buf: &[u8]) { - for i in 0..(buf.len() / 4) { - let mut buf_u32 = [0u8; 4]; - buf_u32.copy_from_slice(&buf[i * 4..i * 4 + 4]); - println!("{:4x}: {:8x}", i * 4, u32::from_le_bytes(buf_u32)); - } -} - -#[allow(unused)] -fn dump_k1_data(k1_buf: &[u32]) { - for i in 0..k1_buf.len() { - if k1_buf[i] != 0 { - println!("{:4x}: {:8x}", i, k1_buf[i]); - } - } -} - -fn main() -> Result<(), Error> { - let event_loop = EventLoop::new(); - let window = WindowBuilder::new() - .with_inner_size(winit::dpi::LogicalSize { - width: (WIDTH_IN_TILES * 8) as f64, - height: (HEIGHT_IN_TILES * 8) as f64, - }) - .with_resizable(false) // currently not supported - .build(&event_loop)?; - - let (instance, surface) = VkInstance::new(Some(&window))?; - unsafe { - let device = instance.device(surface.as_ref())?; - let mut swapchain = instance.swapchain(&device, surface.as_ref().unwrap())?; - - let mut current_frame = 0; - let present_semaphores = (0..NUM_FRAMES) - .map(|_| device.create_semaphore()) - .collect::, Error>>()?; - let frame_fences = (0..NUM_FRAMES) - .map(|_| device.create_fence(false)) - .collect::, Error>>()?; - let mut cmd_buffers = (0..NUM_FRAMES) - .map(|_| device.create_cmd_buf()) - .collect::, Error>>()?; - let query_pools = (0..NUM_FRAMES) - .map(|_| device.create_query_pool(6)) - .collect::, Error>>()?; - - let host = MemFlags::host_coherent(); - let dev = MemFlags::device_local(); - let mut ctx = PietGpuRenderContext::new(); - render_scene(&mut ctx); - let scene = ctx.get_scene_buf(); - //dump_scene(&scene); - let scene_buf = device - .create_buffer(std::mem::size_of_val(&scene[..]) as u64, host) - .unwrap(); - let scene_dev = device - .create_buffer(std::mem::size_of_val(&scene[..]) as u64, dev) - .unwrap(); - device.write_buffer(&scene_buf, &scene)?; - let tilegroup_buf = device.create_buffer(4 * 1024 * 1024, dev)?; - let ptcl_buf = device.create_buffer(48 * 1024 * 1024, dev)?; - let segment_buf = device.create_buffer(64 * 1024 * 1024, dev)?; - let fill_seg_buf = device.create_buffer(64 * 1024 * 1024, dev).unwrap(); - let image_buf = device.create_buffer((WIDTH * HEIGHT * 4) as u64, host)?; - let image_dev = device.create_image2d(WIDTH as u32, HEIGHT as u32, dev)?; - - let k1_alloc_buf_host = device.create_buffer(4, host)?; - let k1_alloc_buf_dev = device.create_buffer(4, dev)?; - let k1_alloc_start = WIDTH_IN_TILEGROUPS * HEIGHT_IN_TILEGROUPS * TILEGROUP_STRIDE; - device.write_buffer(&k1_alloc_buf_host, &[k1_alloc_start as u32])?; - let k1_code = include_bytes!("../shader/kernel1.spv"); - let k1_pipeline = device - .create_simple_compute_pipeline(k1_code, 3, 0) - .unwrap(); - let k1_ds = device - .create_descriptor_set( - &k1_pipeline, - &[&scene_dev, &tilegroup_buf, &k1_alloc_buf_dev], - &[], - ) - .unwrap(); - - let k2s_alloc_buf_host = device.create_buffer(4, host).unwrap(); - let k2s_alloc_buf_dev = device.create_buffer(4, dev).unwrap(); - let k2s_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * K2_PER_TILE_SIZE; - device - .write_buffer(&k2s_alloc_buf_host, &[k2s_alloc_start as u32]) - .unwrap(); - let k2s_code = include_bytes!("../shader/kernel2s.spv"); - let k2s_pipeline = device - .create_simple_compute_pipeline(k2s_code, 4, 0) - .unwrap(); - let k2s_ds = device - .create_descriptor_set( - &k2s_pipeline, - &[&scene_dev, &tilegroup_buf, &segment_buf, &k2s_alloc_buf_dev], - &[], - ) - .unwrap(); - - let k2f_alloc_buf_host = device.create_buffer(4, host).unwrap(); - let k2f_alloc_buf_dev = device.create_buffer(4, dev).unwrap(); - let k2f_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * K2_PER_TILE_SIZE; - device - .write_buffer(&k2f_alloc_buf_host, &[k2f_alloc_start as u32]) - .unwrap(); - let k2f_code = include_bytes!("../shader/kernel2f.spv"); - let k2f_pipeline = device.create_simple_compute_pipeline(k2f_code, 4).unwrap(); - let k2f_ds = device - .create_descriptor_set( - &k2f_pipeline, - &[ - &scene_dev, - &tilegroup_buf, - &fill_seg_buf, - &k2f_alloc_buf_dev, - ], - ) - .unwrap(); - - let k3_alloc_buf_host = device.create_buffer(4, host).unwrap(); - let k3_alloc_buf_dev = device.create_buffer(4, dev).unwrap(); - let k3_alloc_start = WIDTH_IN_TILES * HEIGHT_IN_TILES * PTCL_INITIAL_ALLOC; - device - .write_buffer(&k3_alloc_buf_host, &[k3_alloc_start as u32]) - .unwrap(); - let k3_code = include_bytes!("../shader/kernel3.spv"); - let k3_pipeline = device.create_simple_compute_pipeline(k3_code, 6, 0).unwrap(); - let k3_ds = device - .create_descriptor_set( - &k3_pipeline, - &[ - &scene_dev, - &tilegroup_buf, - &segment_buf, - &fill_seg_buf, - &ptcl_buf, - &k3_alloc_buf_dev, - ], - &[], - ) - .unwrap(); - - let k4_code = include_bytes!("../shader/kernel4.spv"); - let k4_pipeline = device.create_simple_compute_pipeline(k4_code, 3, 1).unwrap(); - let k4_ds = device - .create_descriptor_set(&k4_pipeline, &[&ptcl_buf, &segment_buf, &fill_seg_buf], &[&image_dev]) - .unwrap(); - let query_pool = &query_pools[0]; - let mut cmd_buf = device.create_cmd_buf().unwrap(); - cmd_buf.begin(); - cmd_buf.copy_buffer(&scene_buf, &scene_dev); - // Note: we could use one alloc buf and reuse it. But we'll stick with - // multiple ones for clarity. - cmd_buf.copy_buffer(&k1_alloc_buf_host, &k1_alloc_buf_dev); - cmd_buf.copy_buffer(&k2s_alloc_buf_host, &k2s_alloc_buf_dev); - cmd_buf.copy_buffer(&k2f_alloc_buf_host, &k2f_alloc_buf_dev); - cmd_buf.copy_buffer(&k3_alloc_buf_host, &k3_alloc_buf_dev); - // Note: these clears aren't necessary, and are here to make inspection - // of the buffers cleaner. Can likely be removed. - cmd_buf.clear_buffer(&tilegroup_buf); - cmd_buf.clear_buffer(&ptcl_buf); - cmd_buf.memory_barrier(); - cmd_buf.image_barrier(&image_dev, ImageLayout::Undefined, ImageLayout::General); - cmd_buf.reset_query_pool(&query_pool); - cmd_buf.write_timestamp(&query_pool, 0); - cmd_buf.dispatch( - &k1_pipeline, - &k1_ds, - ((WIDTH / 512) as u32, (HEIGHT / 512) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 1); - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k2s_pipeline, - &k2s_ds, - ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 2); - // Note: this barrier is not necessary (k2f does not depend on - // k2s output), but I'm keeping it here to increase transparency - // of performance. - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k2f_pipeline, - &k2f_ds, - ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 2), - ); - cmd_buf.write_timestamp(&query_pool, 3); - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k3_pipeline, - &k3_ds, - ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 3), - ); - cmd_buf.write_timestamp(&query_pool, 4); - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k4_pipeline, - &k4_ds, - ((WIDTH / TILE_W) as u32, (HEIGHT / TILE_H) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 5); - cmd_buf.memory_barrier(); - cmd_buf.image_barrier(&image_dev, ImageLayout::General, ImageLayout::BlitSrc); - cmd_buf.copy_image_to_buffer(&image_dev, &image_buf); - cmd_buf.finish(); - device.run_cmd_buf(&cmd_buf, &[], &[], Some(&frame_fences[0]))?; - device.wait_and_reset(&[frame_fences[0]])?; - let timestamps = device.reap_query_pool(&query_pool).unwrap(); - println!("Kernel 1 time: {:.3}ms", timestamps[0] * 1e3); - println!( - "Kernel 2s time: {:.3}ms", - (timestamps[1] - timestamps[0]) * 1e3 - ); - println!( - "Kernel 2f time: {:.3}ms", - (timestamps[2] - timestamps[1]) * 1e3 - ); - println!( - "Kernel 3 time: {:.3}ms", - (timestamps[3] - timestamps[2]) * 1e3 - ); - println!( - "Render time: {:.3}ms", - (timestamps[4] - timestamps[3]) * 1e3 - ); - - /* - let mut k1_data: Vec = Default::default(); - device.read_buffer(&segment_buf, &mut k1_data).unwrap(); - dump_k1_data(&k1_data); - */ - - if false { - let mut img_data: Vec = Default::default(); - // Note: because png can use a `&[u8]` slice, we could avoid an extra copy - // (probably passing a slice into a closure). But for now: keep it simple. - device.read_buffer(&image_buf, &mut img_data).unwrap(); - - // Write image as PNG file. - let path = Path::new("image.png"); - let file = File::create(path).unwrap(); - let ref mut w = BufWriter::new(file); - - let mut encoder = png::Encoder::new(w, WIDTH as u32, HEIGHT as u32); - encoder.set_color(png::ColorType::RGBA); - encoder.set_depth(png::BitDepth::Eight); - let mut writer = encoder.write_header().unwrap(); - - writer.write_image_data(&img_data).unwrap(); - } - - event_loop.run(move |event, _, control_flow| { - *control_flow = ControlFlow::Wait; - - match event { - Event::WindowEvent { event, window_id } if window_id == window.id() => { - match event { - WindowEvent::CloseRequested => { - *control_flow = ControlFlow::Exit; - } - _ => (), - } - } - Event::MainEventsCleared => { - window.request_redraw(); - } - Event::RedrawRequested(window_id) if window_id == window.id() => { - let frame_idx = current_frame % NUM_FRAMES; - let query_pool = &query_pools[frame_idx]; - - if current_frame >= NUM_FRAMES { - device.wait_and_reset(&[frame_fences[frame_idx]]).unwrap(); - - let timestamps = device.reap_query_pool(query_pool).unwrap(); - window.set_title(&format!("k1: {:.3}ms, k2: {:.3}ms, k3: {:.3}ms, k4: {:.3}ms", - timestamps[0] * 1e3, - (timestamps[1] - timestamps[0]) * 1e3, - (timestamps[2] - timestamps[1]) * 1e3, - (timestamps[3] - timestamps[2]) * 1e3, - )); - } - - let (image_idx, acquisition_semaphore) = swapchain.next().unwrap(); - let swap_image = swapchain.image(image_idx); - let cmd_buf = &mut cmd_buffers[frame_idx]; - cmd_buf.begin(); - cmd_buf.reset_query_pool(&query_pool); - cmd_buf.copy_buffer(&scene_buf, &scene_dev); - cmd_buf.copy_buffer(&k1_alloc_buf_host, &k1_alloc_buf_dev); - cmd_buf.copy_buffer(&k2s_alloc_buf_host, &k2s_alloc_buf_dev); - cmd_buf.copy_buffer(&k3_alloc_buf_host, &k3_alloc_buf_dev); - cmd_buf.clear_buffer(&tilegroup_buf); - cmd_buf.clear_buffer(&ptcl_buf); - cmd_buf.memory_barrier(); - cmd_buf.write_timestamp(&query_pool, 0); - cmd_buf.dispatch( - &k1_pipeline, - &k1_ds, - ((WIDTH / 512) as u32, (HEIGHT / 512) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 1); - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k2s_pipeline, - &k2s_ds, - ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 2); - cmd_buf.memory_barrier(); - cmd_buf.dispatch( - &k3_pipeline, - &k3_ds, - ((WIDTH / 512) as u32, (HEIGHT / 16) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 3); - cmd_buf.memory_barrier(); - cmd_buf.image_barrier(&image_dev, ImageLayout::BlitSrc, ImageLayout::General); - cmd_buf.dispatch( - &k4_pipeline, - &k4_ds, - ((WIDTH / TILE_W) as u32, (HEIGHT / TILE_H) as u32, 1), - ); - cmd_buf.write_timestamp(&query_pool, 4); - cmd_buf.memory_barrier(); - cmd_buf.image_barrier( - &swap_image, - ImageLayout::Undefined, - ImageLayout::BlitDst, - ); - cmd_buf.image_barrier(&image_dev, ImageLayout::General, ImageLayout::BlitSrc); - cmd_buf.blit_image(&image_dev, &swap_image); - cmd_buf.image_barrier( - &swap_image, - ImageLayout::BlitDst, - ImageLayout::Present, - ); - cmd_buf.finish(); - - device - .run_cmd_buf( - &cmd_buf, - &[acquisition_semaphore], - &[present_semaphores[frame_idx]], - Some(&frame_fences[frame_idx]), - ) - .unwrap(); - - swapchain - .present(image_idx, &[present_semaphores[frame_idx]]) - .unwrap(); - - current_frame += 1; - } - _ => (), - } - }) - } -}