diff --git a/.gitignore b/.gitignore index 42f08a0ec..e8eb5dd6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target/ *.spv *.exrc +rust-toolchain diff --git a/Cargo.lock b/Cargo.lock index 0b57a1a76..c0a4b1af7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,20 +9,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "adler32" -version = "1.2.0" +name = "ahash" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", +] [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" + +[[package]] +name = "ar" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" + [[package]] name = "arrayvec" version = "0.7.2" @@ -30,10 +68,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] -name = "async-trait" -version = "0.1.53" +name = "ash" +version = "0.37.1+1.3.235" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "911015c962d56e2e4052f40182ca5462ba60a3d2ff04e827c365a0ab3d65726d" +dependencies = [ + "libloading", +] + +[[package]] +name = "async-trait" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" dependencies = [ "proc-macro2", "quote", @@ -59,15 +106,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "bezier-rs" version = "0.1.0" dependencies = [ - "glam", + "glam 0.17.3", ] [[package]] @@ -75,7 +122,7 @@ name = "bezier-rs-wasm" version = "0.0.0" dependencies = [ "bezier-rs", - "glam", + "glam 0.17.3", "js-sys", "log", "serde", @@ -97,6 +144,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[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 = "borrow_stack" version = "0.1.0" @@ -105,16 +161,39 @@ dependencies = [ ] [[package]] -name = "bumpalo" -version = "3.9.1" +name = "bstr" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "byteorder" @@ -122,12 +201,65 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +dependencies = [ + "jobserver", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "winapi", +] + +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -144,6 +276,43 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "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" @@ -176,35 +345,94 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", "memoffset", - "once_cell", "scopeguard", ] [[package]] -name = "crossbeam-utils" -version = "0.8.11" +name = "crossbeam-queue" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ "cfg-if", - "once_cell", + "crossbeam-utils", ] [[package]] -name = "deflate" -version = "1.0.0" +name = "crossbeam-utils" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ - "adler32", + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[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 = "cxx" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -218,12 +446,28 @@ dependencies = [ "syn", ] +[[package]] +name = "deunicode" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690" + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dyn-any" version = "0.2.1" dependencies = [ "dyn-any-derive", - "glam", + "glam 0.17.3", "log", ] @@ -264,9 +508,9 @@ dependencies = [ [[package]] name = "exr" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c26a90d9dd411a3d119d6f55752fb4c134ca243250c32fb9cab7b2561638d2" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" dependencies = [ "bit_field", "flume", @@ -278,10 +522,19 @@ dependencies = [ ] [[package]] -name = "flate2" -version = "1.0.24" +name = "fastrand" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", "miniz_oxide", @@ -307,22 +560,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "futures-core" -version = "0.3.23" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" +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 = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-sink" -version = "0.3.23" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +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.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "js-sys", @@ -347,24 +634,63 @@ version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01732b97afd8508eee3333a541b9f7610f454bb818669e66e90f5f57c93a776" dependencies = [ - "num-traits", "serde", ] +[[package]] +name = "glam" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" +dependencies = [ + "num-traits", +] + +[[package]] +name = "globset" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] + [[package]] name = "graph-craft" version = "0.1.0" dependencies = [ + "anyhow", "borrow_stack", + "bytemuck", "dyn-any", "dyn-clone", - "glam", + "glam 0.17.3", "graphene-core", "graphene-std", "log", "num-traits", + "nvtx", "rand_chacha", "serde", + "spirv-builder", + "tempfile", + "tera", + "vulkano", ] [[package]] @@ -383,6 +709,7 @@ name = "graphene-core" version = "0.1.0" dependencies = [ "async-trait", + "bytemuck", "dyn-any", "serde", "spirv-std", @@ -396,7 +723,7 @@ dependencies = [ "borrow_stack", "dyn-any", "dyn-clone", - "glam", + "glam 0.17.3", "graph-proc-macros", "graphene-core", "image", @@ -419,7 +746,7 @@ dependencies = [ "derivative", "dyn-any", "env_logger", - "glam", + "glam 0.17.3", "graph-craft", "graphene-core", "graphene-std", @@ -444,7 +771,7 @@ version = "0.0.0" dependencies = [ "base64", "bezier-rs", - "glam", + "glam 0.17.3", "graph-craft", "graphene-std", "image", @@ -483,9 +810,33 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "ad6a9459c9c30b177b925162351f97e7d967c7ea8bab3b8352805327daf45554" +dependencies = [ + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -496,6 +847,12 @@ dependencies = [ "libc", ] +[[package]] +name = "humansize" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026" + [[package]] name = "humantime" version = "2.1.0" @@ -503,10 +860,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] -name = "image" -version = "0.24.3" +name = "iana-time-zone" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30ca2ecf7666107ff827a8e481de6a132a9b687ed3bb20bb1c144a36c00964" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ignore" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" +dependencies = [ + "crossbeam-utils", + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" dependencies = [ "bytemuck", "byteorder", @@ -522,33 +921,61 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "1.0.1" +name = "indexmap" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "jobserver" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +dependencies = [ + "libc", +] [[package]] name = "jpeg-decoder" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" dependencies = [ "rayon", ] [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] [[package]] name = "kurbo" -version = "0.8.3" -source = "git+https://github.com/linebender/kurbo.git#9ed4b73dac4f085065d7a6968121581cb8296089" +version = "0.9.0" +source = "git+https://github.com/linebender/kurbo.git#fd839c25ea0c98576c7ce5789305822675a89938" dependencies = [ "arrayvec", "serde", @@ -568,21 +995,40 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.124" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] [[package]] name = "libm" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da83a57f3f5ba3680950aa3cbc806fc297bc0b289d42e8942ed528ace71b8145" +checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg", "scopeguard", @@ -590,33 +1036,42 @@ dependencies = [ [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] -name = "memchr" -version = "2.4.1" +name = "malloc_buf" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] @@ -663,19 +1118,158 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.13.0" +name = "nvtx" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "358dc398b07348e7541bf065ee313e8215a7832e07fab385f51683dc3be83ec7" +dependencies = [ + "cc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pest" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f400b0f7905bf702f9f3dc3df5a121b16c54e9e8012c082905fdf09a931861a" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "423c2ba011d6e27b02b482a3707c773d19aec65cc024637aec44e19652e66f63" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e64e6c2c85031c02fdbd9e5c72845445ca0a724d419aa0bc068ac620c9935c1" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57959b91f0a133f89a68be874a5c88ed689c19cd729ecdb5d762ebf16c64d662" +dependencies = [ + "once_cell", + "pest", + "sha1", +] + +[[package]] +name = "phf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +dependencies = [ + "siphasher", + "uncased", +] [[package]] name = "pin-project" @@ -699,21 +1293,21 @@ dependencies = [ [[package]] name = "png" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" dependencies = [ "bitflags", "crc32fast", - "deflate", + "flate2", "miniz_oxide", ] [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -741,11 +1335,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -761,13 +1355,24 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -780,17 +1385,25 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-string" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0501e134c6905fee1f10fed25b0a7e1261bf676cffac9543a7d0730dec01af2" [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" dependencies = [ - "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -798,9 +1411,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -809,10 +1422,19 @@ dependencies = [ ] [[package]] -name = "regex" -version = "1.5.5" +name = "redox_syscall" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -821,15 +1443,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remain" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7" +checksum = "1a81bc6a3aaeb180f767bd2bda8c03bac5b93b3b69a783c66f35d16a4df276cf" dependencies = [ "proc-macro2", "quote", @@ -837,10 +1459,68 @@ dependencies = [ ] [[package]] -name = "rustybuzz" -version = "0.5.0" +name = "remove_dir_all" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ff94f20221325d000e552781713e53b0d85c1d9551b6f420d12daf5a08eace" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] +name = "rspirv" +version = "0.11.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1503993b59ca9ae4127365c3293517576d7ce56be9f3d8abb1625c85ddc583ba" +dependencies = [ + "fxhash", + "num-traits", + "spirv", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc_codegen_spirv" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu?branch=main#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" +dependencies = [ + "ar", + "hashbrown 0.11.2", + "indexmap", + "libc", + "num-traits", + "once_cell", + "regex", + "rspirv", + "rustc-demangle", + "rustc_codegen_spirv-types", + "sanitize-filename", + "serde", + "serde_json", + "smallvec", + "spirv-tools", + "syn", +] + +[[package]] +name = "rustc_codegen_spirv-types" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu?branch=main#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" +dependencies = [ + "rspirv", + "serde", +] + +[[package]] +name = "rustybuzz" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9e34ecf6900625412355a61bda0bd68099fe674de707c67e5e4aed2c05e489" dependencies = [ "bitflags", "bytemuck", @@ -854,15 +1534,34 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +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 = "sanitize-filename" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +dependencies = [ + "lazy_static", + "regex", +] [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scoped_threadpool" @@ -877,21 +1576,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "serde" -version = "1.0.136" +name = "scratch" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "serde" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" dependencies = [ "serde_derive", ] [[package]] name = "serde-wasm-bindgen" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0927d4115e78b52dfd4cabcb3cc79bd56b94a53cf27c074bf8b83af1765d1" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ - "fnv", "js-sys", "serde", "wasm-bindgen", @@ -899,9 +1603,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" dependencies = [ "proc-macro2", "quote", @@ -910,9 +1614,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -920,57 +1624,162 @@ dependencies = [ ] [[package]] -name = "smallvec" -version = "1.8.0" +name = "sha1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slug" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373" +dependencies = [ + "deunicode", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "spin" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" dependencies = [ "lock_api", ] [[package]] -name = "spirv-std" -version = "0.4.0-alpha.12" -source = "git+https://github.com/EmbarkStudios/rust-gpu#0866cf591a7fdbbd15bdb3468e192bb9b6189fd0" +name = "spirv" +version = "0.2.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" dependencies = [ "bitflags", - "glam", + "num-traits", +] + +[[package]] +name = "spirv-builder" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu?branch=main#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" +dependencies = [ + "memchr", + "raw-string", + "rustc_codegen_spirv", + "rustc_codegen_spirv-types", + "serde", + "serde_json", +] + +[[package]] +name = "spirv-std" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" +dependencies = [ + "bitflags", + "glam 0.22.0", "num-traits", "spirv-std-macros", - "spirv-types", + "spirv-std-types", ] [[package]] name = "spirv-std-macros" -version = "0.4.0-alpha.12" -source = "git+https://github.com/EmbarkStudios/rust-gpu#0866cf591a7fdbbd15bdb3468e192bb9b6189fd0" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" dependencies = [ "proc-macro2", "quote", - "spirv-types", + "spirv-std-types", "syn", ] [[package]] -name = "spirv-types" -version = "0.4.0-alpha.12" -source = "git+https://github.com/EmbarkStudios/rust-gpu#0866cf591a7fdbbd15bdb3468e192bb9b6189fd0" +name = "spirv-std-types" +version = "0.4.0-alpha.17" +source = "git+https://github.com/EmbarkStudios/rust-gpu#acb05d379982f35e6d4fbd85ff28af3e9876cf4c" + +[[package]] +name = "spirv-tools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc7c8ca2077515286505bd3ccd396e55ac5706e80322e1d6d22a82e1cad4f7c3" +dependencies = [ + "memchr", + "spirv-tools-sys", + "tempfile", +] + +[[package]] +name = "spirv-tools-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b32d9d6469cd6b50dcd6bd841204b5946b4fb7b70a97872717cdc417659c9a" +dependencies = [ + "cc", +] [[package]] name = "syn" -version = "1.0.91" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] +name = "tera" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df578c295f9ec044ff1c829daf31bb7581d5b3c2a7a3d87419afe1f2531438c" +dependencies = [ + "chrono", + "chrono-tz", + "globwalk", + "humansize", + "lazy_static", + "percent-encoding", + "pest", + "pest_derive", + "rand", + "regex", + "serde", + "serde_json", + "slug", + "unic-segment", ] [[package]] @@ -984,18 +1793,18 @@ dependencies = [ [[package]] name = "test-case" -version = "2.1.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196e8a70562e252cc51eaaaee3ecddc39803d9b7fd4a772b7c7dae7cdf42a859" +checksum = "21d6cf5a7dffb3f9dceec8e6b8ca528d9bd71d36c9f074defb548ce161f598c0" dependencies = [ "test-case-macros", ] [[package]] name = "test-case-macros" -version = "2.1.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd461f47ade621665c9f4e44b20449341769911c253275dc5cb03726cbb852c" +checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26" dependencies = [ "cfg-if", "proc-macro-error", @@ -1006,24 +1815,33 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -1035,9 +1853,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65" +checksum = "f17def29300a156c19ae30814710d9c63cd50288a49c6fd3a10ccfbe4cf886fd" dependencies = [ "flate2", "jpeg-decoder", @@ -1046,9 +1864,80 @@ dependencies = [ [[package]] name = "ttf-parser" -version = "0.15.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74c96594835e10fa545e2a51e8709f30b173a092bfd6036ef2cec53376244f3" +checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff" + +[[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 = "uncased" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +dependencies = [ + "version_check", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] [[package]] name = "unicode-bidi-mirroring" @@ -1064,21 +1953,27 @@ checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" [[package]] name = "unicode-general-category" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742" +checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" [[package]] name = "unicode-script" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dd944fd05f2f0b5c674917aea8a4df6af84f2d8de3fe8d988b95d28fb8fb09" +checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-width" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "version_check" @@ -1086,6 +1981,52 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vk-parse" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6a0bda9bbe6b9e50e6456c80aa8fe4cca3b21e4311a1130c41e4915ec2e32a" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "vulkano" +version = "0.31.0" +source = "git+https://github.com/GraphiteEditor/vulkano?branch=fix_rust_gpu#dbec4e91030c60849caccaa3b933fc2aac0d327b" +dependencies = [ + "ahash 0.8.2", + "ash", + "bytemuck", + "core-graphics-types", + "crossbeam-queue", + "half", + "heck", + "indexmap", + "lazy_static", + "libloading", + "objc", + "parking_lot", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "smallvec", + "vk-parse", +] + +[[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.11.0+wasi-snapshot-preview1" @@ -1094,9 +2035,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "serde", @@ -1106,13 +2047,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1121,9 +2062,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -1133,9 +2074,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1143,9 +2084,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -1156,15 +2097,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasm-bindgen-test" -version = "0.3.30" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4464b3f74729a25f42b1a0cd9e6a515d2f25001f3535a6cfaf35d34a4de3bab" +checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d" dependencies = [ "console_error_panic_hook", "js-sys", @@ -1176,9 +2117,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.30" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c5a6f82cc6093a321ca5fb3dc9327fe51675d477b3799b4a9375bac3b7b4c" +checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7" dependencies = [ "proc-macro2", "quote", @@ -1186,9 +2127,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -1230,3 +2171,66 @@ 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 = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" diff --git a/about.toml b/about.toml index 4921efabe..db09c5bff 100644 --- a/about.toml +++ b/about.toml @@ -2,7 +2,10 @@ accepted = [ "Apache-2.0", "MIT", "BSD-3-Clause", + "BSD-2-Clause", "Zlib", + "Unicode-DFS-2016", + "ISC", ] ignore-build-dependencies = true ignore-dev-dependencies = true diff --git a/deny.toml b/deny.toml index 0d4fed347..c8d244c63 100644 --- a/deny.toml +++ b/deny.toml @@ -73,7 +73,11 @@ allow = [ "MIT", "Apache-2.0", "BSD-3-Clause", + "BSD-2-Clause", "Zlib", + "Zlib", + "Unicode-DFS-2016", + "ISC", #"Apache-2.0 WITH LLVM-exception", ] # List of explicitly disallowed licenses @@ -173,8 +177,8 @@ skip = [ #{ name = "ansi_term", version = "=0.11.0" }, { name = "cfg-if", version = "=0.1.10" }, ] -# Similarly to `skip` allows you to skip certain crates during duplicate -# detection. Unlike skip, it also includes the entire tree of transitive +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive # dependencies starting at the specified crate, up to a certain depth, which is # by default infinite skip-tree = [ diff --git a/graphene/src/layers/nodegraph_layer.rs b/graphene/src/layers/nodegraph_layer.rs index b9745219a..c5da7cb61 100644 --- a/graphene/src/layers/nodegraph_layer.rs +++ b/graphene/src/layers/nodegraph_layer.rs @@ -9,6 +9,7 @@ use glam::{DAffine2, DMat2, DVec2}; use graph_craft::proto::Type; use kurbo::{Affine, BezPath, Shape as KurboShape}; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; use std::fmt::Write; #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] @@ -131,7 +132,7 @@ impl Default for NodeGraphFrameLayer { DocumentNode { name: "Input".into(), inputs: vec![NodeInput::Network], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic])), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic(Cow::Borrowed("T"))])), metadata: DocumentNodeMetadata { position: (8, 4) }, }, ), @@ -140,7 +141,7 @@ impl Default for NodeGraphFrameLayer { DocumentNode { name: "Output".into(), inputs: vec![NodeInput::Node(0)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic])), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic(Cow::Borrowed("T"))])), metadata: DocumentNodeMetadata { position: (20, 4) }, }, ), diff --git a/node-graph/gcore/Cargo.toml b/node-graph/gcore/Cargo.toml index 794159755..8ab1eb479 100644 --- a/node-graph/gcore/Cargo.toml +++ b/node-graph/gcore/Cargo.toml @@ -10,14 +10,16 @@ license = "MIT OR Apache-2.0" [features] std = ["dyn-any"] -default = ["async"] -gpu = ["spirv-std"] +default = ["async", "serde"] +gpu = ["spirv-std", "bytemuck"] async = ["async-trait"] nightly = [] +serde = ["dep:serde"] [dependencies] dyn-any = {path = "../../libraries/dyn-any", features = ["derive"], optional = true} spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu", features = ["glam"] , optional = true} +bytemuck = {version = "1.8", features = ["derive"], optional = true} async-trait = {version = "0.1", optional = true} -serde = {version = "1.0", features = ["derive"]} +serde = {version = "1.0", features = ["derive"], optional = true} diff --git a/node-graph/gcore/src/gpu.rs b/node-graph/gcore/src/gpu.rs new file mode 100644 index 000000000..04ddf7294 --- /dev/null +++ b/node-graph/gcore/src/gpu.rs @@ -0,0 +1,8 @@ +use bytemuck::{Pod, Zeroable}; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Pod, Zeroable)] +pub struct PushConstants { + pub n: u32, + pub node: u32, +} diff --git a/node-graph/gcore/src/lib.rs b/node-graph/gcore/src/lib.rs index 11f0f3753..feccb4ec8 100644 --- a/node-graph/gcore/src/lib.rs +++ b/node-graph/gcore/src/lib.rs @@ -1,6 +1,4 @@ #![no_std] -#![cfg_attr(target_arch = "spirv", feature(register_attr), register_attr(spirv))] - #[cfg(feature = "async")] extern crate alloc; @@ -11,20 +9,18 @@ use async_trait::async_trait; pub mod generic; pub mod ops; -pub mod raster; pub mod structural; pub mod value; +#[cfg(feature = "gpu")] +pub mod gpu; + +pub mod raster; + pub trait Node { type Output; fn eval(self, input: T) -> Self::Output; - fn input(&self) -> &str { - core::any::type_name::() - } - fn output(&self) -> &str { - core::any::type_name::() - } } trait Input { diff --git a/node-graph/gcore/src/ops.rs b/node-graph/gcore/src/ops.rs index a8f82a06f..7f7a3a27e 100644 --- a/node-graph/gcore/src/ops.rs +++ b/node-graph/gcore/src/ops.rs @@ -3,7 +3,7 @@ use core::ops::Add; use crate::{Node, RefNode}; -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct AddNode; impl<'n, L: Add + 'n, R, O: 'n> Node<(L, R)> for AddNode { type Output = >::Output; @@ -30,6 +30,12 @@ impl<'n, L: Add + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for } } +impl AddNode { + pub fn new() -> Self { + Self + } +} + #[cfg(feature = "std")] pub mod dynamic { use super::*; @@ -156,7 +162,7 @@ impl<'n, T: Clone + 'n> Node for DupNode { } /// Return the Input Argument -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct IdNode; impl Node for IdNode { type Output = T; @@ -177,6 +183,12 @@ impl RefNode for IdNode { } } +impl IdNode { + pub fn new() -> Self { + Self + } +} + pub struct MapResultNode(pub MN, pub PhantomData<(I, E)>); impl, I, E> Node> for MapResultNode { diff --git a/node-graph/gcore/src/raster.rs b/node-graph/gcore/src/raster.rs index 8d2fe92d0..0cef45f7d 100644 --- a/node-graph/gcore/src/raster.rs +++ b/node-graph/gcore/src/raster.rs @@ -1,8 +1,7 @@ use crate::Node; -use self::color::Color; - pub mod color; +use self::color::Color; #[derive(Debug, Clone, Copy)] pub struct GrayscaleColorNode; diff --git a/node-graph/gcore/src/raster/color.rs b/node-graph/gcore/src/raster/color.rs index 84b406057..37dab7e07 100644 --- a/node-graph/gcore/src/raster/color.rs +++ b/node-graph/gcore/src/raster/color.rs @@ -1,5 +1,6 @@ #[cfg(feature = "std")] use dyn_any::{DynAny, StaticType}; +#[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// Structure that represents a color. @@ -8,7 +9,7 @@ use serde::{Deserialize, Serialize}; /// the values encode the brightness of each channel proportional to the light intensity in cd/m² (nits) in HDR, and `0.0` (black) to `1.0` (white) in SDR color. #[repr(C)] #[cfg_attr(feature = "std", derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize, DynAny))] -#[cfg_attr(not(feature = "std"), derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize))] +#[cfg_attr(not(feature = "std"), derive(Debug, Clone, Copy, PartialEq, Default))] pub struct Color { red: f32, green: f32, @@ -35,11 +36,13 @@ impl Color { /// let color = Color::from_rgbaf32(1.0, 1.0, 1.0, f32::NAN); /// assert!(color == None); /// ``` + #[cfg(not(target_arch = "spirv"))] pub fn from_rgbaf32(red: f32, green: f32, blue: f32, alpha: f32) -> Option { if alpha > 1. || [red, green, blue, alpha].iter().any(|c| c.is_sign_negative() || !c.is_finite()) { return None; } - Some(Color { red, green, blue, alpha }) + let color = Color { red, green, blue, alpha }; + Some(color) } /// Return an opaque `Color` from given `f32` RGB channels. @@ -230,6 +233,7 @@ impl Color { /// use graphene_core::raster::color::Color; /// let color = Color::from_rgba_str("7C67FA61").unwrap(); /// ``` + #[cfg(not(target_arch = "spirv"))] pub fn from_rgba_str(color_str: &str) -> Option { if color_str.len() != 8 { return None; @@ -247,6 +251,7 @@ impl Color { /// use graphene_core::raster::color::Color; /// let color = Color::from_rgb_str("7C67FA").unwrap(); /// ``` + #[cfg(not(target_arch = "spirv"))] pub fn from_rgb_str(color_str: &str) -> Option { if color_str.len() != 6 { return None; diff --git a/node-graph/graph-craft/Cargo.toml b/node-graph/graph-craft/Cargo.toml index 44a9402f3..3e08e97fc 100644 --- a/node-graph/graph-craft/Cargo.toml +++ b/node-graph/graph-craft/Cargo.toml @@ -4,10 +4,16 @@ version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" +[features] +default = [] +profiling = ["nvtx", "gpu"] +gpu = ["serde", "vulkano", "spirv-builder", "tera", "graphene-core/gpu"] +serde = ["dep:serde", "graphene-std/serde", "glam/serde"] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -graphene-core = { path = "../gcore", features = ["async", "std"] } +graphene-core = { path = "../gcore", features = ["async", "std" ] } graphene-std = { path = "../gstd" } dyn-any = { path = "../../libraries/dyn-any", features = ["log-bad-types", "rc", "glam"] } num-traits = "0.2" @@ -18,5 +24,10 @@ log = "0.4" serde = { version = "1", features = ["derive", "rc"], optional = true } glam = { version = "0.17" } -[features] -serde = ["dep:serde", "graphene-std/serde", "glam/serde"] +vulkano = {git = "https://github.com/GraphiteEditor/vulkano", branch = "fix_rust_gpu", optional = true} +bytemuck = {version = "1.8" } +nvtx = {version = "1.1.1", optional = true} +tempfile = "3" +spirv-builder = {git = "https://github.com/EmbarkStudios/rust-gpu" , branch = "main", optional = true, default-features = false, features=["use-installed-tools"]} +tera = {version = "1.17.1", optional = true} +anyhow = "1.0.66" diff --git a/node-graph/graph-craft/src/document.rs b/node-graph/graph-craft/src/document.rs index e21077e36..1355b596a 100644 --- a/node-graph/graph-craft/src/document.rs +++ b/node-graph/graph-craft/src/document.rs @@ -1,3 +1,4 @@ +use crate::generic; use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNetwork, ProtoNode, ProtoNodeInput, Type}; use std::collections::HashMap; use std::sync::Mutex; @@ -193,7 +194,7 @@ impl NodeNetwork { let value_node = DocumentNode { name: name.clone(), inputs: vec![NodeInput::Value { tagged_value, exposed }], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::value::ValueNode", &[Type::Generic])), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::value::ValueNode", &[generic!("T")])), metadata: DocumentNodeMetadata::default(), }; assert!(!self.nodes.contains_key(&new_id)); @@ -209,7 +210,7 @@ impl NodeNetwork { } } } - node.implementation = DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic])); + node.implementation = DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[generic!("T")])); node.inputs = vec![NodeInput::Node(inner_network.output)]; for node_id in new_nodes { self.flatten_with_fns(node_id, map_ids, gen_id); @@ -256,8 +257,8 @@ mod test { DocumentNode { name: "Cons".into(), inputs: vec![NodeInput::Network, NodeInput::Network], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")])), }, ), ( @@ -265,8 +266,8 @@ mod test { DocumentNode { name: "Add".into(), inputs: vec![NodeInput::Node(0)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[generic!("T"), generic!("U")])), }, ), ] @@ -288,8 +289,8 @@ mod test { DocumentNode { name: "Cons".into(), inputs: vec![NodeInput::Network, NodeInput::Network], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")])), }, ), ( @@ -297,8 +298,8 @@ mod test { DocumentNode { name: "Add".into(), inputs: vec![NodeInput::Node(1)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[generic!("T"), generic!("U")])), }, ), ] @@ -344,13 +345,13 @@ mod test { let document_node = DocumentNode { name: "Cons".into(), inputs: vec![NodeInput::Network, NodeInput::Node(0)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")])), }; let proto_node = document_node.resolve_proto_node(); let reference = ProtoNode { - identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic]), + identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")]), input: ProtoNodeInput::Network, construction_args: ConstructionArgs::Nodes(vec![0]), }; @@ -366,7 +367,7 @@ mod test { ( 1, ProtoNode { - identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic]), + identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[generic!("T")]), input: ProtoNodeInput::Node(11), construction_args: ConstructionArgs::Nodes(vec![]), }, @@ -374,7 +375,7 @@ mod test { ( 10, ProtoNode { - identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic]), + identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")]), input: ProtoNodeInput::Network, construction_args: ConstructionArgs::Nodes(vec![14]), }, @@ -382,7 +383,7 @@ mod test { ( 11, ProtoNode { - identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Generic, Type::Generic]), + identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[generic!("T"), generic!("U")]), input: ProtoNodeInput::Node(10), construction_args: ConstructionArgs::Nodes(vec![]), }, @@ -410,8 +411,8 @@ mod test { DocumentNode { name: "Inc".into(), inputs: vec![NodeInput::Node(11)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode", &[generic!("T")])), }, ), ( @@ -419,8 +420,8 @@ mod test { DocumentNode { name: "Cons".into(), inputs: vec![NodeInput::Network, NodeInput::Node(14)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("T"), generic!("U")])), }, ), ( @@ -431,8 +432,8 @@ mod test { tagged_value: value::TaggedValue::U32(2), exposed: false, }], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::value::ValueNode", &[Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::value::ValueNode", &[generic!("T")])), }, ), ( @@ -440,8 +441,8 @@ mod test { DocumentNode { name: "Add".into(), inputs: vec![NodeInput::Node(10)], - implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Generic, Type::Generic])), metadata: DocumentNodeMetadata::default(), + implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::AddNode", &[generic!("T"), generic!("U")])), }, ), ] diff --git a/node-graph/graph-craft/src/executor.rs b/node-graph/graph-craft/src/executor.rs new file mode 100644 index 000000000..b9bb4eab5 --- /dev/null +++ b/node-graph/graph-craft/src/executor.rs @@ -0,0 +1,54 @@ +use std::error::Error; + +use borrow_stack::{BorrowStack, FixedSizeStack}; +use graphene_core::Node; +use graphene_std::any::{Any, TypeErasedNode}; + +use crate::{document::NodeNetwork, node_registry::push_node, proto::ProtoNetwork}; + +pub struct Compiler {} + +impl Compiler { + pub fn compile(&self, mut network: NodeNetwork, resolve_inputs: bool) -> ProtoNetwork { + let node_count = network.nodes.len(); + println!("flattening"); + for id in 0..node_count { + network.flatten(id as u64); + } + let mut proto_network = network.into_proto_network(); + if resolve_inputs { + println!("resolving inputs"); + proto_network.resolve_inputs(); + } + println!("reordering ids"); + proto_network.reorder_ids(); + proto_network + } +} + +pub trait Executor { + fn execute(&self, input: Any<'static>) -> Result, Box>; +} + +pub struct DynamicExecutor { + stack: FixedSizeStack>, +} + +impl DynamicExecutor { + pub fn new(proto_network: ProtoNetwork) -> Self { + assert_eq!(proto_network.inputs.len(), 1); + let node_count = proto_network.nodes.len(); + let stack = FixedSizeStack::new(node_count); + for (_id, node) in proto_network.nodes { + push_node(node, &stack); + } + Self { stack } + } +} + +impl Executor for DynamicExecutor { + fn execute(&self, input: Any<'static>) -> Result, Box> { + let result = unsafe { self.stack.get().last().unwrap().eval(input) }; + Ok(result) + } +} diff --git a/node-graph/graph-craft/src/gpu.rs b/node-graph/graph-craft/src/gpu.rs new file mode 100644 index 000000000..dabd26be9 --- /dev/null +++ b/node-graph/graph-craft/src/gpu.rs @@ -0,0 +1,3 @@ +pub mod compiler; +pub mod context; +pub mod executor; diff --git a/node-graph/graph-craft/src/gpu/compiler.rs b/node-graph/graph-craft/src/gpu/compiler.rs new file mode 100644 index 000000000..36522548d --- /dev/null +++ b/node-graph/graph-craft/src/gpu/compiler.rs @@ -0,0 +1,137 @@ +use std::path::Path; + +use crate::proto::*; +use tera::Context; + +fn create_cargo_toml(metadata: &Metadata) -> Result { + let mut tera = tera::Tera::default(); + tera.add_raw_template("cargo_toml", include_str!("templates/Cargo-template.toml"))?; + let mut context = Context::new(); + context.insert("name", &metadata.name); + context.insert("authors", &metadata.authors); + context.insert("gcore_path", &format!("{}{}", env!("CARGO_MANIFEST_DIR"), "/../gcore")); + tera.render("cargo_toml", &context) +} + +pub struct Metadata { + name: String, + authors: Vec, +} + +impl Metadata { + pub fn new(name: String, authors: Vec) -> Self { + Self { name, authors } + } +} + +pub fn create_files(matadata: &Metadata, network: &ProtoNetwork, compile_dir: &Path, input_type: &str, output_type: &str) -> anyhow::Result<()> { + let src = compile_dir.join("src"); + let cargo_file = compile_dir.join("Cargo.toml"); + let cargo_toml = create_cargo_toml(matadata)?; + std::fs::write(cargo_file, cargo_toml)?; + + // create src dir + match std::fs::create_dir(&src) { + Ok(_) => {} + Err(e) => { + if e.kind() != std::io::ErrorKind::AlreadyExists { + return Err(e.into()); + } + } + } + let lib = src.join("lib.rs"); + let shader = serialize_gpu(network, input_type, output_type)?; + println!("{}", shader); + std::fs::write(lib, shader)?; + Ok(()) +} + +pub fn serialize_gpu(network: &ProtoNetwork, input_type: &str, output_type: &str) -> anyhow::Result { + assert_eq!(network.inputs.len(), 1); + /*let input = &network.nodes[network.inputs[0] as usize].1; + let output = &network.nodes[network.output as usize].1; + let input_type = format!("{}::Input", input.identifier.fully_qualified_name()); + let output_type = format!("{}::Output", output.identifier.fully_qualified_name()); + */ + + fn nid(id: &u64) -> String { + format!("n{id}") + } + + let mut nodes = Vec::new(); + #[derive(serde::Serialize)] + struct Node { + id: String, + fqn: String, + args: Vec, + } + for (ref id, node) in network.nodes.iter() { + let fqn = &node.identifier.name; + let id = nid(id); + + nodes.push(Node { + id, + fqn: fqn.to_string(), + args: node.construction_args.new_function_args(), + }); + } + + let template = include_str!("templates/spirv-template.rs"); + let mut tera = tera::Tera::default(); + tera.add_raw_template("spirv", template)?; + let mut context = Context::new(); + context.insert("input_type", &input_type); + context.insert("output_type", &output_type); + context.insert("nodes", &nodes); + context.insert("last_node", &nid(&network.output)); + context.insert("compute_threads", &64); + Ok(tera.render("spirv", &context)?) +} + +use spirv_builder::{MetadataPrintout, SpirvBuilder, SpirvMetadata}; +pub fn compile(dir: &Path) -> Result { + let result = SpirvBuilder::new(dir, "spirv-unknown-spv1.5") + .print_metadata(MetadataPrintout::DependencyOnly) + .multimodule(false) + .preserve_bindings(true) + .release(true) + //.relax_struct_store(true) + //.relax_block_layout(true) + .spirv_metadata(SpirvMetadata::Full) + .build()?; + + Ok(result) +} + +#[cfg(test)] +mod test { + + #[test] + fn test_create_cargo_toml() { + let cargo_toml = super::create_cargo_toml(&super::Metadata { + name: "project".to_owned(), + authors: vec!["Example ".to_owned(), "smith.john@example.com".to_owned()], + }); + let cargo_toml = cargo_toml.expect("failed to build carog toml template"); + let lines = cargo_toml.split('\n').collect::>(); + let cargo_toml = lines[..lines.len() - 2].join("\n"); + let reference = r#"[package] +name = "project-node" +version = "0.1.0" +authors = ["Example ", "smith.john@example.com", ] +edition = "2021" +license = "MIT OR Apache-2.0" +publish = false + +[lib] +crate-type = ["dylib", "lib"] + +[patch.crates-io] +libm = { git = "https://github.com/rust-lang/libm", tag = "0.2.5" } + +[dependencies] +spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu" , features= ["glam"]}"#; + + assert_eq!(cargo_toml, reference); + } +} diff --git a/node-graph/graph-craft/src/gpu/context.rs b/node-graph/graph-craft/src/gpu/context.rs new file mode 100644 index 000000000..10ec02887 --- /dev/null +++ b/node-graph/graph-craft/src/gpu/context.rs @@ -0,0 +1,68 @@ +use std::sync::Arc; +use vulkano::{ + command_buffer::allocator::StandardCommandBufferAllocator, + descriptor_set::allocator::StandardDescriptorSetAllocator, + device::{Device, DeviceCreateInfo, Queue, QueueCreateInfo}, + instance::{Instance, InstanceCreateInfo}, + memory::allocator::StandardMemoryAllocator, + VulkanLibrary, +}; + +#[derive(Debug)] +pub struct Context { + pub instance: Arc, + pub device: Arc, + pub queue: Arc, + pub allocator: StandardMemoryAllocator, + pub command_buffer_allocator: StandardCommandBufferAllocator, + pub descriptor_set_allocator: StandardDescriptorSetAllocator, +} + +impl Context { + pub fn new() -> Self { + let library = VulkanLibrary::new().unwrap(); + let instance = Instance::new(library, InstanceCreateInfo::default()).expect("failed to create instance"); + let physical = instance.enumerate_physical_devices().expect("could not enumerate devices").next().expect("no device available"); + for family in physical.queue_family_properties() { + println!("Found a queue family with {:?} queue(s)", family.queue_count); + } + let queue_family_index = physical + .queue_family_properties() + .iter() + .enumerate() + .position(|(_, q)| q.queue_flags.graphics) + .expect("couldn't find a graphical queue family") as u32; + + let (device, mut queues) = Device::new( + physical, + DeviceCreateInfo { + // here we pass the desired queue family to use by index + queue_create_infos: vec![QueueCreateInfo { + queue_family_index, + ..Default::default() + }], + ..Default::default() + }, + ) + .expect("failed to create device"); + let queue = queues.next().unwrap(); + let alloc = StandardMemoryAllocator::new_default(device.clone()); + let calloc = StandardCommandBufferAllocator::new(device.clone()); + let dalloc = StandardDescriptorSetAllocator::new(device.clone()); + + Self { + instance, + device, + queue, + allocator: alloc, + command_buffer_allocator: calloc, + descriptor_set_allocator: dalloc, + } + } +} + +impl Default for Context { + fn default() -> Self { + Self::new() + } +} diff --git a/node-graph/graph-craft/src/gpu/executor.rs b/node-graph/graph-craft/src/gpu/executor.rs new file mode 100644 index 000000000..ae29a1b8b --- /dev/null +++ b/node-graph/graph-craft/src/gpu/executor.rs @@ -0,0 +1,188 @@ +use std::path::Path; + +use super::{compiler::Metadata, context::Context}; +use crate::gpu::compiler; +use bytemuck::Pod; +use dyn_any::StaticTypeSized; +use vulkano::{ + buffer::{self, BufferUsage, CpuAccessibleBuffer}, + command_buffer::{allocator::StandardCommandBufferAllocator, AutoCommandBufferBuilder, CommandBufferUsage}, + descriptor_set::{allocator::StandardDescriptorSetAllocator, PersistentDescriptorSet, WriteDescriptorSet}, + device::Device, + memory::allocator::StandardMemoryAllocator, + pipeline::{ComputePipeline, Pipeline, PipelineBindPoint}, + sync::GpuFuture, +}; + +use crate::proto::*; +use graphene_core::gpu::PushConstants; + +#[derive(Debug)] +pub struct GpuExecutor { + context: Context, + entry_point: String, + shader: std::sync::Arc, + _phantom: std::marker::PhantomData<(I, O)>, +} + +impl GpuExecutor { + pub fn new(context: Context, network: ProtoNetwork, metadata: Metadata, compile_dir: &Path) -> anyhow::Result { + compiler::create_files(&metadata, &network, compile_dir, std::any::type_name::(), std::any::type_name::())?; + let result = compiler::compile(compile_dir)?; + + let bytes = std::fs::read(result.module.unwrap_single())?; + let shader = unsafe { vulkano::shader::ShaderModule::from_bytes(context.device.clone(), &bytes)? }; + let entry_point = result.entry_points.first().expect("No entry points").clone(); + + Ok(Self { + context, + entry_point, + shader, + _phantom: std::marker::PhantomData, + }) + } +} + +impl crate::executor::Executor for GpuExecutor { + fn execute(&self, input: graphene_std::any::Any<'static>) -> Result, Box> { + let input = dyn_any::downcast::>(input).expect("Wrong input type"); + let context = &self.context; + let result: Vec = execute_shader( + context.device.clone(), + context.queue.clone(), + self.shader.entry_point(&self.entry_point).expect("Entry point not found in shader"), + &context.allocator, + &context.command_buffer_allocator, + *input, + ); + Ok(Box::new(result)) + } +} + +fn execute_shader( + device: std::sync::Arc, + queue: std::sync::Arc, + entry_point: vulkano::shader::EntryPoint, + alloc: &StandardMemoryAllocator, + calloc: &StandardCommandBufferAllocator, + data: Vec, +) -> Vec { + let constants = PushConstants { n: data.len() as u32, node: 0 }; + + let dest_data: Vec<_> = (0..constants.n).map(|_| O::zeroed()).collect(); + let source_buffer = create_buffer(data, alloc).expect("failed to create buffer"); + let dest_buffer = create_buffer(dest_data, alloc).expect("failed to create buffer"); + + let compute_pipeline = ComputePipeline::new(device.clone(), entry_point, &(), None, |_| {}).expect("failed to create compute pipeline"); + let layout = compute_pipeline.layout().set_layouts().get(0).unwrap(); + let dalloc = StandardDescriptorSetAllocator::new(device.clone()); + let set = PersistentDescriptorSet::new( + &dalloc, + layout.clone(), + [ + WriteDescriptorSet::buffer(0, source_buffer), // 0 is the binding + WriteDescriptorSet::buffer(1, dest_buffer.clone()), + ], + ) + .unwrap(); + let mut builder = AutoCommandBufferBuilder::primary(calloc, queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit).unwrap(); + + builder + .bind_pipeline_compute(compute_pipeline.clone()) + .bind_descriptor_sets(PipelineBindPoint::Compute, compute_pipeline.layout().clone(), 0, set) + .push_constants(compute_pipeline.layout().clone(), 0, constants) + .dispatch([1024, 1, 1]) + .unwrap(); + let command_buffer = builder.build().unwrap(); + + let future = vulkano::sync::now(device).then_execute(queue, command_buffer).unwrap().then_signal_fence_and_flush().unwrap(); + #[cfg(feature = "profiling")] + nvtx::range_push!("compute"); + future.wait(None).unwrap(); + #[cfg(feature = "profiling")] + nvtx::range_pop!(); + let content = dest_buffer.read().unwrap(); + content.to_vec() +} + +fn create_buffer(data: Vec, alloc: &StandardMemoryAllocator) -> Result>, vulkano::memory::allocator::AllocationCreationError> { + let buffer_usage = BufferUsage { + storage_buffer: true, + transfer_src: true, + transfer_dst: true, + ..Default::default() + }; + + buffer::CpuAccessibleBuffer::from_iter(alloc, buffer_usage, false, data.into_iter()) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::concrete; + use crate::generic; + use crate::gpu::compiler; + + fn inc_network() -> ProtoNetwork { + let mut construction_network = ProtoNetwork { + inputs: vec![10], + output: 1, + nodes: [ + ( + 1, + ProtoNode { + identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[generic!("u32")]), + input: ProtoNodeInput::Node(11), + construction_args: ConstructionArgs::Nodes(vec![]), + }, + ), + ( + 10, + ProtoNode { + identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[generic!("&ValueNode"), generic!("()")]), + input: ProtoNodeInput::Network, + construction_args: ConstructionArgs::Nodes(vec![14]), + }, + ), + ( + 11, + ProtoNode { + identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[generic!("u32"), generic!("u32")]), + input: ProtoNodeInput::Node(10), + construction_args: ConstructionArgs::Nodes(vec![]), + }, + ), + ( + 14, + ProtoNode { + identifier: NodeIdentifier::new("graphene_core::value::ValueNode", &[concrete!("u32")]), + input: ProtoNodeInput::None, + construction_args: ConstructionArgs::Value(Box::new(3_u32)), + }, + ), + ] + .into_iter() + .collect(), + }; + construction_network.resolve_inputs(); + construction_network.reorder_ids(); + construction_network + } + + #[test] + fn add_on_gpu() { + use crate::executor::Executor; + let m = compiler::Metadata::new("project".to_owned(), vec!["test@example.com".to_owned()]); + let network = inc_network(); + let temp_dir = tempfile::tempdir().expect("failed to create tempdir"); + + let executor: GpuExecutor = GpuExecutor::new(Context::new(), network, m, temp_dir.path()).unwrap(); + + let data: Vec<_> = (0..1024).map(|x| x as u32).collect(); + let result = executor.execute(Box::new(data)).unwrap(); + let result = dyn_any::downcast::>(result).unwrap(); + for (i, r) in result.iter().enumerate() { + assert_eq!(*r, i as u32 + 3); + } + } +} diff --git a/node-graph/graph-craft/src/gpu/templates/Cargo-template.toml b/node-graph/graph-craft/src/gpu/templates/Cargo-template.toml new file mode 100644 index 000000000..7f58b530a --- /dev/null +++ b/node-graph/graph-craft/src/gpu/templates/Cargo-template.toml @@ -0,0 +1,17 @@ +[package] +name = "{{name}}-node" +version = "0.1.0" +authors = [{%for author in authors%}"{{author}}", {%endfor%}] +edition = "2021" +license = "MIT OR Apache-2.0" +publish = false + +[lib] +crate-type = ["dylib", "lib"] + +[patch.crates-io] +libm = { git = "https://github.com/rust-lang/libm", tag = "0.2.5" } + +[dependencies] +spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu" , features= ["glam"]} +graphene-core = {path = "{{gcore_path}}", default-features = false, features = ["gpu"]} diff --git a/node-graph/graph-craft/src/gpu/templates/spirv-template.rs b/node-graph/graph-craft/src/gpu/templates/spirv-template.rs new file mode 100644 index 000000000..c5a6626a5 --- /dev/null +++ b/node-graph/graph-craft/src/gpu/templates/spirv-template.rs @@ -0,0 +1,38 @@ +#![no_std] +#![feature(unchecked_math)] +#![deny(warnings)] + +#[cfg(target_arch = "spirv")] +extern crate spirv_std; + +#[cfg(target_arch = "spirv")] +pub mod gpu { + use super::*; + use spirv_std::spirv; + use spirv_std::glam::UVec3; + + #[allow(unused)] + #[spirv(compute(threads({{compute_threads}})))] + pub fn eval ( + #[spirv(global_invocation_id)] global_id: UVec3, + #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[{{input_type}}], + #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [{{output_type}}], + #[spirv(push_constant)] push_consts: &graphene_core::gpu::PushConstants, + ) { + let gid = global_id.x as usize; + // Only process up to n, which is the length of the buffers. + if global_id.x < push_consts.n { + y[gid] = node_graph(a[gid]); + } + } + + fn node_graph(input: {{input_type}}) -> {{output_type}} { + use graphene_core::Node; + + {% for node in nodes %} + let {{node.id}} = {{node.fqn}}::new({% for arg in node.args %}{{arg}}, {% endfor %}); + {% endfor %} + {{last_node}}.eval(input) + } + +} diff --git a/node-graph/graph-craft/src/lib.rs b/node-graph/graph-craft/src/lib.rs index d5818964b..c6002d3d2 100644 --- a/node-graph/graph-craft/src/lib.rs +++ b/node-graph/graph-craft/src/lib.rs @@ -6,6 +6,11 @@ pub mod node_registry; pub mod document; pub mod proto; +pub mod executor; + +#[cfg(feature = "gpu")] +pub mod gpu; + #[cfg(test)] mod tests { @@ -15,7 +20,6 @@ mod tests { use graphene_core::{structural::*, RefNode}; use borrow_stack::BorrowStack; - use borrow_stack::FixedSizeStack; use dyn_any::{downcast, IntoDynAny}; use graphene_std::any::{Any, DowncastNode, DynAnyNode, TypeErasedNode}; use graphene_std::ops::AddNode; @@ -56,9 +60,7 @@ mod tests { #[test] fn execute_add() { use crate::document::*; - use crate::node_registry::push_node; use crate::proto::*; - use graphene_core::Node; fn add_network() -> NodeNetwork { NodeNetwork { @@ -95,7 +97,7 @@ mod tests { } } - let mut network = NodeNetwork { + let network = NodeNetwork { inputs: vec![0], output: 0, nodes: [( @@ -117,18 +119,14 @@ mod tests { .collect(), }; - let stack = FixedSizeStack::new(256); - println!("flattening"); - network.flatten(0); - //println!("flat_network: {:#?}", network); - let mut proto_network = network.into_proto_network(); - proto_network.reorder_ids(); - //println!("reordered_ides: {:#?}", proto_network); - for (_id, node) in proto_network.nodes { - push_node(node, &stack); - } + use crate::executor::{Compiler, DynamicExecutor, Executor}; - let result = unsafe { stack.get().last().unwrap().eval(32_u32.into_dyn()) }; + let compiler = Compiler {}; + let protograph = compiler.compile(network, false); + + let exec = DynamicExecutor::new(protograph); + + let result = exec.execute(32_u32.into_dyn()).unwrap(); let val = *dyn_any::downcast::(result).unwrap(); assert_eq!(val, 33_u32); } diff --git a/node-graph/graph-craft/src/node_registry.rs b/node-graph/graph-craft/src/node_registry.rs index 63a6432ac..2dff018ac 100644 --- a/node-graph/graph-craft/src/node_registry.rs +++ b/node-graph/graph-craft/src/node_registry.rs @@ -1,9 +1,7 @@ -use std::borrow::Cow; - use borrow_stack::FixedSizeStack; use glam::DVec2; use graphene_core::generic::FnNode; -use graphene_core::ops::AddNode; +use graphene_core::ops::{AddNode, IdNode}; use graphene_core::raster::color::Color; use graphene_core::structural::{ConsNode, Then}; use graphene_core::Node; @@ -13,105 +11,78 @@ use graphene_std::raster::Image; use graphene_std::vector::subpath::Subpath; use crate::proto::Type; -use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNode, ProtoNodeInput, Type::Concrete}; +use crate::proto::{ConstructionArgs, NodeIdentifier, ProtoNode, ProtoNodeInput}; type NodeConstructor = fn(ProtoNode, &FixedSizeStack>); +use crate::{concrete, generic}; + //TODO: turn into hasmap static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ - ( - NodeIdentifier::new("graphene_core::ops::IdNode", &[Concrete(std::borrow::Cow::Borrowed("Any<'_>"))]), - |proto_node, stack| { - stack.push_fn(|nodes| { - if let ProtoNodeInput::Node(pre_id) = proto_node.input { - let pre_node = nodes.get(pre_id as usize).unwrap(); - let node = pre_node.then(graphene_core::ops::IdNode); - node.into_type_erased() - } else { - graphene_core::ops::IdNode.into_type_erased() - } - }) - }, - ), - (NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Generic]), |proto_node, stack| { + (NodeIdentifier::new("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]), |proto_node, stack| { stack.push_fn(|nodes| { if let ProtoNodeInput::Node(pre_id) = proto_node.input { let pre_node = nodes.get(pre_id as usize).unwrap(); - let node = pre_node.then(graphene_core::ops::IdNode); - node.into_type_erased() + pre_node.into_type_erased() } else { graphene_core::ops::IdNode.into_type_erased() } }) }), - ( - NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Add Node constructed with out rhs input node") }; - let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); - let input_node: DowncastBothNode<_, (), f64> = DowncastBothNode::new(value_node); - let node: DynAnyNode<_, f64, _, _> = DynAnyNode::new(ConsNode::new(input_node).then(graphene_core::ops::AddNode)); - - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new( - "graphene_core::ops::AddNode", - &[Concrete(std::borrow::Cow::Borrowed("u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), - |proto_node, stack| { - stack.push_fn(|nodes| { - let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); - let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); - let node = (pre_node).then(node); + (NodeIdentifier::new("graphene_core::ops::IdNode", &[generic!("T")]), |proto_node, stack| { + stack.push_fn(|nodes| { + if let ProtoNodeInput::Node(pre_id) = proto_node.input { + let pre_node = nodes.get(pre_id as usize).unwrap(); + pre_node.into_type_erased() + } else { + graphene_core::ops::IdNode.into_type_erased() + } + }) + }), + (NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Add Node constructed with out rhs input node") }; + let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); + let input_node: DowncastBothNode<_, (), f32> = DowncastBothNode::new(value_node); + let node: DynAnyNode<_, f32, _, _> = DynAnyNode::new(ConsNode::new(input_node).then(graphene_core::ops::AddNode)); + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { node.into_type_erased() - }) - }, - ), - ( - NodeIdentifier::new( - "graphene_core::ops::AddNode", - &[Concrete(std::borrow::Cow::Borrowed("&u32")), Concrete(std::borrow::Cow::Borrowed("&u32"))], - ), - |proto_node, stack| { - stack.push_fn(|nodes| { - let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); - let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); - let node = (pre_node).then(node); + } + }) + }), + (NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("u32"), concrete!("u32")]), |proto_node, stack| { + stack.push_fn(|nodes| { + let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); + let node = (pre_node).then(node); - node.into_type_erased() - }) - }, - ), - ( - NodeIdentifier::new( - "graphene_core::ops::AddNode", - &[Concrete(std::borrow::Cow::Borrowed("&u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), - |proto_node, stack| { - stack.push_fn(|nodes| { - let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); - let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); - let node = (pre_node).then(node); + node.into_type_erased() + }) + }), + (NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("&u32"), concrete!("&u32")]), |proto_node, stack| { + stack.push_fn(|nodes| { + let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); + let node = (pre_node).then(node); - node.into_type_erased() - }) - }, - ), + node.into_type_erased() + }) + }), + (NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("&u32"), concrete!("u32")]), |proto_node, stack| { + stack.push_fn(|nodes| { + let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + let node: DynAnyNode = DynAnyNode::new(graphene_core::ops::AddNode); + let node = (pre_node).then(node); + + node.into_type_erased() + }) + }), ( - NodeIdentifier::new( - "graphene_core::structural::ConsNode", - &[Concrete(std::borrow::Cow::Borrowed("&u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), + NodeIdentifier::new("graphene_core::structural::ConsNode", &[concrete!("&u32"), concrete!("u32")]), |proto_node, stack| { if let ConstructionArgs::Nodes(cons_node_arg) = proto_node.construction_args { stack.push_fn(move |nodes| { @@ -135,10 +106,7 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ }, ), ( - NodeIdentifier::new( - "graphene_core::structural::ConsNode", - &[Concrete(std::borrow::Cow::Borrowed("u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), + NodeIdentifier::new("graphene_core::structural::ConsNode", &[concrete!("u32"), concrete!("u32")]), |proto_node, stack| { if let ConstructionArgs::Nodes(cons_node_arg) = proto_node.construction_args { stack.push_fn(move |nodes| { @@ -163,10 +131,7 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ ), // TODO: create macro to impl for all types ( - NodeIdentifier::new( - "graphene_core::structural::ConsNode", - &[Concrete(std::borrow::Cow::Borrowed("&u32")), Concrete(std::borrow::Cow::Borrowed("&u32"))], - ), + NodeIdentifier::new("graphene_core::structural::ConsNode", &[concrete!("&u32"), concrete!("&u32")]), |proto_node, stack| { let node_id = proto_node.input.unwrap_node() as usize; if let ConstructionArgs::Nodes(cons_node_arg) = proto_node.construction_args { @@ -184,31 +149,25 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ } }, ), - ( - NodeIdentifier::new("graphene_core::any::DowncastNode", &[Concrete(std::borrow::Cow::Borrowed("&u32"))]), - |proto_node, stack| { - stack.push_fn(|nodes| { - let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); - let node = pre_node.then(graphene_core::ops::IdNode); - node.into_type_erased() - }) - }, - ), - ( - NodeIdentifier::new("graphene_core::value::ValueNode", &[Concrete(std::borrow::Cow::Borrowed("Any<'_>"))]), - |proto_node, stack| { - stack.push_fn(|_nodes| { - if let ConstructionArgs::Value(value) = proto_node.construction_args { - let node = FnNode::new(move |_| value.clone().up_box() as Any<'static>); + (NodeIdentifier::new("graphene_core::any::DowncastNode", &[concrete!("&u32")]), |proto_node, stack| { + stack.push_fn(|nodes| { + let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + let node = pre_node.then(graphene_core::ops::IdNode); + node.into_type_erased() + }) + }), + (NodeIdentifier::new("graphene_core::value::ValueNode", &[concrete!("Any<'>")]), |proto_node, stack| { + stack.push_fn(|_nodes| { + if let ConstructionArgs::Value(value) = proto_node.construction_args { + let node = FnNode::new(move |_| value.clone().up_box() as Any<'static>); - node.into_type_erased() - } else { - unreachable!() - } - }) - }, - ), - (NodeIdentifier::new("graphene_core::value::ValueNode", &[Type::Generic]), |proto_node, stack| { + node.into_type_erased() + } else { + unreachable!() + } + }) + }), + (NodeIdentifier::new("graphene_core::value::ValueNode", &[generic!("T")]), |proto_node, stack| { stack.push_fn(|_nodes| { if let ConstructionArgs::Value(value) = proto_node.construction_args { let node = FnNode::new(move |_| value.clone().up_box() as Any<'static>); @@ -230,44 +189,38 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ } }) }), - ( - NodeIdentifier::new("graphene_core::raster::BrightenColorNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - info!("proto node {:?}", proto_node); - stack.push_fn(|nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Brighten Color Node constructed with out brightness input node") }; - let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); - let input_node: DowncastBothNode<_, (), f32> = DowncastBothNode::new(value_node); - let node = DynAnyNode::new(graphene_core::raster::BrightenColorNode::new(input_node)); + (NodeIdentifier::new("graphene_core::raster::BrightenColorNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + info!("proto node {:?}", proto_node); + stack.push_fn(|nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Brighten Color Node constructed with out brightness input node") }; + let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); + let input_node: DowncastBothNode<_, (), f32> = DowncastBothNode::new(value_node); + let node = DynAnyNode::new(graphene_core::raster::BrightenColorNode::new(input_node)); - if let ProtoNodeInput::Node(pre_id) = proto_node.input { - let pre_node = nodes.get(pre_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new("graphene_core::raster::HueShiftColorNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - info!("proto node {:?}", proto_node); - stack.push_fn(|nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Hue Shift Color Node constructed with out shift input node") }; - let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); - let input_node: DowncastBothNode<_, (), f32> = DowncastBothNode::new(value_node); - let node = DynAnyNode::new(graphene_core::raster::HueShiftColorNode::new(input_node)); + if let ProtoNodeInput::Node(pre_id) = proto_node.input { + let pre_node = nodes.get(pre_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { + node.into_type_erased() + } + }) + }), + (NodeIdentifier::new("graphene_core::raster::HueShiftColorNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + info!("proto node {:?}", proto_node); + stack.push_fn(|nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Hue Shift Color Node constructed with out shift input node") }; + let value_node = nodes.get(construction_nodes[0] as usize).unwrap(); + let input_node: DowncastBothNode<_, (), f32> = DowncastBothNode::new(value_node); + let node = DynAnyNode::new(graphene_core::raster::HueShiftColorNode::new(input_node)); - if let ProtoNodeInput::Node(pre_id) = proto_node.input { - let pre_node = nodes.get(pre_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), + if let ProtoNodeInput::Node(pre_id) = proto_node.input { + let pre_node = nodes.get(pre_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { + node.into_type_erased() + } + }) + }), (NodeIdentifier::new("graphene_std::raster::MapImageNode", &[]), |proto_node, stack| { if let ConstructionArgs::Nodes(operation_node_id) = proto_node.construction_args { stack.push_fn(move |nodes| { @@ -311,28 +264,24 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ } }) }), - ( - NodeIdentifier::new("graphene_std::raster::HueSaturationNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("HueSaturationNode Node constructed without inputs") }; + (NodeIdentifier::new("graphene_std::raster::HueSaturationNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("HueSaturationNode Node constructed without inputs") }; - let hue: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); - let saturation: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[1] as usize).unwrap()); - let lightness: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[2] as usize).unwrap()); - let node = DynAnyNode::new(graphene_std::raster::HueSaturationNode::new(hue, saturation, lightness)); - - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), + let hue: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); + let saturation: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[1] as usize).unwrap()); + let lightness: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[2] as usize).unwrap()); + let node = DynAnyNode::new(graphene_std::raster::HueSaturationNode::new(hue, saturation, lightness)); + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { + node.into_type_erased() + } + }) + }), ( - NodeIdentifier::new("graphene_std::raster::BrightnessContrastNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), + NodeIdentifier::new("graphene_std::raster::BrightnessContrastNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { stack.push_fn(move |nodes| { let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("BrightnessContrastNode Node constructed without inputs") }; @@ -350,102 +299,81 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ }) }, ), - ( - NodeIdentifier::new("graphene_std::raster::GammaNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("GammaNode Node constructed without inputs") }; - let gamma: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); - let node = DynAnyNode::new(graphene_std::raster::GammaNode::new(gamma)); + (NodeIdentifier::new("graphene_std::raster::GammaNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("GammaNode Node constructed without inputs") }; + let gamma: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); + let node = DynAnyNode::new(graphene_std::raster::GammaNode::new(gamma)); - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new("graphene_std::raster::OpacityNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("OpacityNode Node constructed without inputs") }; - let opacity: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); - let node = DynAnyNode::new(graphene_std::raster::OpacityNode::new(opacity)); - - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new("graphene_std::raster::PosterizeNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Posterize node constructed without inputs") }; - let value: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); - let node = DynAnyNode::new(graphene_std::raster::PosterizeNode::new(value)); - - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new("graphene_std::raster::ExposureNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]), - |proto_node, stack| { - stack.push_fn(move |nodes| { - let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("ExposureNode constructed without inputs") }; - let value: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); - let node = DynAnyNode::new(graphene_std::raster::ExposureNode::new(value)); - - if let ProtoNodeInput::Node(node_id) = proto_node.input { - let pre_node = nodes.get(node_id as usize).unwrap(); - (pre_node).then(node).into_type_erased() - } else { - node.into_type_erased() - } - }) - }, - ), - ( - NodeIdentifier::new("graphene_std::raster::ImageNode", &[Concrete(std::borrow::Cow::Borrowed("&str"))]), - |_proto_node, stack| { - stack.push_fn(|_nodes| { - let image = FnNode::new(|s: &str| graphene_std::raster::image_node::<&str>().eval(s).unwrap()); - let node: DynAnyNode<_, &str, _, _> = DynAnyNode::new(image); + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { node.into_type_erased() - }) - }, - ), - ( - NodeIdentifier::new("graphene_std::raster::ExportImageNode", &[Concrete(std::borrow::Cow::Borrowed("&str"))]), - |proto_node, stack| { - stack.push_fn(|nodes| { - let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + } + }) + }), + (NodeIdentifier::new("graphene_std::raster::OpacityNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("OpacityNode Node constructed without inputs") }; + let opacity: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); + let node = DynAnyNode::new(graphene_std::raster::OpacityNode::new(opacity)); - let image = FnNode::new(|input: (Image, &str)| graphene_std::raster::export_image_node().eval(input).unwrap()); - let node: DynAnyNode<_, (Image, &str), _, _> = DynAnyNode::new(image); - let node = (pre_node).then(node); + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { node.into_type_erased() - }) - }, - ), + } + }) + }), + (NodeIdentifier::new("graphene_std::raster::PosterizeNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("Posterize node constructed without inputs") }; + let value: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); + let node = DynAnyNode::new(graphene_std::raster::PosterizeNode::new(value)); + + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { + node.into_type_erased() + } + }) + }), + (NodeIdentifier::new("graphene_std::raster::ExposureNode", &[concrete!("&TypeErasedNode")]), |proto_node, stack| { + stack.push_fn(move |nodes| { + let ConstructionArgs::Nodes(construction_nodes) = proto_node.construction_args else { unreachable!("ExposureNode constructed without inputs") }; + let value: DowncastBothNode<_, (), f64> = DowncastBothNode::new(nodes.get(construction_nodes[0] as usize).unwrap()); + let node = DynAnyNode::new(graphene_std::raster::ExposureNode::new(value)); + + if let ProtoNodeInput::Node(node_id) = proto_node.input { + let pre_node = nodes.get(node_id as usize).unwrap(); + (pre_node).then(node).into_type_erased() + } else { + node.into_type_erased() + } + }) + }), + (NodeIdentifier::new("graphene_std::raster::ImageNode", &[concrete!("&str")]), |_proto_node, stack| { + stack.push_fn(|_nodes| { + let image = FnNode::new(|s: &str| graphene_std::raster::image_node::<&str>().eval(s).unwrap()); + let node: DynAnyNode<_, &str, _, _> = DynAnyNode::new(image); + node.into_type_erased() + }) + }), + (NodeIdentifier::new("graphene_std::raster::ExportImageNode", &[concrete!("&str")]), |proto_node, stack| { + stack.push_fn(|nodes| { + let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap(); + + let image = FnNode::new(|input: (Image, &str)| graphene_std::raster::export_image_node().eval(input).unwrap()); + let node: DynAnyNode<_, (Image, &str), _, _> = DynAnyNode::new(image); + let node = (pre_node).then(node); + node.into_type_erased() + }) + }), ( - NodeIdentifier::new( - "graphene_core::structural::ConsNode", - &[Concrete(std::borrow::Cow::Borrowed("Image")), Concrete(std::borrow::Cow::Borrowed("&str"))], - ), + NodeIdentifier::new("graphene_core::structural::ConsNode", &[concrete!("Image"), concrete!("&str")]), |proto_node, stack| { let node_id = proto_node.input.unwrap_node() as usize; if let ConstructionArgs::Nodes(cons_node_arg) = proto_node.construction_args { @@ -504,11 +432,19 @@ static NODE_REGISTRY: &[(NodeIdentifier, NodeConstructor)] = &[ }), ]; -pub fn push_node(proto_node: ProtoNode, stack: &FixedSizeStack>) { +pub fn push_node<'a>(proto_node: ProtoNode, stack: &'a FixedSizeStack>) { if let Some((_id, f)) = NODE_REGISTRY.iter().find(|(id, _)| *id == proto_node.identifier) { f(proto_node, stack); } else { - panic!("NodeImplementation: {:?} not found in Registry", proto_node.identifier); + let other_types = NODE_REGISTRY + .iter() + .map(|(id, _)| id) + .filter(|id| id.name.as_ref() == proto_node.identifier.name.as_ref()) + .collect::>(); + panic!( + "NodeImplementation: {:?} not found in Registry types for which the node is implemented:\n {:#?}", + proto_node.identifier, other_types + ); } } @@ -530,20 +466,14 @@ mod protograph_testing { let cons_protonode = ProtoNode { construction_args: ConstructionArgs::Nodes(vec![1]), input: ProtoNodeInput::Node(0), - identifier: NodeIdentifier::new( - "graphene_core::structural::ConsNode", - &[Concrete(std::borrow::Cow::Borrowed("u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), + identifier: NodeIdentifier::new("graphene_core::structural::ConsNode", &[concrete!("u32"), concrete!("u32")]), }; push_node(cons_protonode, &stack); let add_protonode = ProtoNode { construction_args: ConstructionArgs::Nodes(vec![]), input: ProtoNodeInput::Node(2), - identifier: NodeIdentifier::new( - "graphene_core::ops::AddNode", - &[Concrete(std::borrow::Cow::Borrowed("u32")), Concrete(std::borrow::Cow::Borrowed("u32"))], - ), + identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("u32"), concrete!("u32")]), }; push_node(add_protonode, &stack); @@ -576,7 +506,7 @@ mod protograph_testing { let image_protonode = ProtoNode { construction_args: ConstructionArgs::Nodes(vec![]), input: ProtoNodeInput::None, - identifier: NodeIdentifier::new("graphene_std::raster::ImageNode", &[Concrete(std::borrow::Cow::Borrowed("&str"))]), + identifier: NodeIdentifier::new("graphene_std::raster::ImageNode", &[concrete!("&str")]), }; push_node(image_protonode, &stack); @@ -591,7 +521,7 @@ mod protograph_testing { let image_protonode = ProtoNode { construction_args: ConstructionArgs::Nodes(vec![]), input: ProtoNodeInput::None, - identifier: NodeIdentifier::new("graphene_std::raster::ImageNode", &[Concrete(std::borrow::Cow::Borrowed("&str"))]), + identifier: NodeIdentifier::new("graphene_std::raster::ImageNode", &[concrete!("&str")]), }; push_node(image_protonode, &stack); diff --git a/node-graph/graph-craft/src/proto.rs b/node-graph/graph-craft/src/proto.rs index b0665d3fd..177b29263 100644 --- a/node-graph/graph-craft/src/proto.rs +++ b/node-graph/graph-craft/src/proto.rs @@ -1,8 +1,22 @@ +use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use crate::document::value; use crate::document::NodeId; +#[macro_export] +macro_rules! concrete { + ($type:expr) => { + Type::Concrete(std::borrow::Cow::Borrowed($type)) + }; +} +#[macro_export] +macro_rules! generic { + ($type:expr) => { + Type::Generic(std::borrow::Cow::Borrowed($type)) + }; +} + #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct NodeIdentifier { @@ -10,10 +24,26 @@ pub struct NodeIdentifier { pub types: std::borrow::Cow<'static, [Type]>, } +impl NodeIdentifier { + pub fn fully_qualified_name(&self) -> String { + let mut name = String::new(); + name.push_str(self.name.as_ref()); + name.push('<'); + for t in self.types.as_ref() { + name.push_str(t.to_string().as_str()); + name.push_str(", "); + } + name.pop(); + name.pop(); + name.push('>'); + name + } +} + #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Type { - Generic, + Generic(std::borrow::Cow<'static, str>), Concrete(std::borrow::Cow<'static, str>), } @@ -22,6 +52,14 @@ impl From<&'static str> for Type { Type::Concrete(std::borrow::Cow::Borrowed(s)) } } +impl std::fmt::Display for Type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Type::Generic(name) => write!(f, "{}", name), + Type::Concrete(name) => write!(f, "{}", name), + } + } +} impl Type { pub const fn from_str(concrete: &'static str) -> Self { @@ -70,6 +108,15 @@ impl PartialEq for ConstructionArgs { } } +impl ConstructionArgs { + pub fn new_function_args(&self) -> Vec { + match self { + ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("n{}", n)).collect(), + ConstructionArgs::Value(value) => vec![format!("{:?}", value)], + } + } +} + #[derive(Debug, PartialEq)] pub struct ProtoNode { pub construction_args: ConstructionArgs, @@ -77,7 +124,7 @@ pub struct ProtoNode { pub identifier: NodeIdentifier, } -#[derive(Debug, Default, PartialEq, Eq)] +#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)] pub enum ProtoNodeInput { None, #[default] @@ -97,7 +144,7 @@ impl ProtoNodeInput { impl ProtoNode { pub fn value(value: ConstructionArgs) -> Self { Self { - identifier: NodeIdentifier::new("graphene_core::value::ValueNode", &[Type::Generic]), + identifier: NodeIdentifier::new("graphene_core::value::ValueNode", &[Type::Generic(Cow::Borrowed("T"))]), construction_args: value, input: ProtoNodeInput::None, } @@ -165,6 +212,41 @@ impl ProtoNetwork { edges } + pub fn resolve_inputs(&mut self) { + while !self.resolve_inputs_impl() {} + } + fn resolve_inputs_impl(&mut self) -> bool { + self.reorder_ids(); + + let mut lookup = self.nodes.iter().map(|(id, _)| (*id, *id)).collect::>(); + let compose_node_id = self.nodes.len() as NodeId; + let inputs = self.nodes.iter().map(|(_, node)| node.input).collect::>(); + + if let Some((input_node, id, input)) = self.nodes.iter_mut().find_map(|(id, node)| { + if let ProtoNodeInput::Node(input_node) = node.input { + node.input = ProtoNodeInput::None; + let pre_node_input = inputs.get(input_node as usize).expect("input node should exist"); + Some((input_node, *id, *pre_node_input)) + } else { + None + } + }) { + lookup.insert(id, compose_node_id); + self.replace_node_references(&lookup); + self.nodes.push(( + compose_node_id, + ProtoNode { + identifier: NodeIdentifier::new("graphene_core::structural::ComposeNode", &[generic!("T"), Type::Generic(Cow::Borrowed("U"))]), + construction_args: ConstructionArgs::Nodes(vec![input_node, id]), + input, + }, + )); + return false; + } + + true + } + // Based on https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search // This approach excludes nodes that are not connected pub fn topological_sort(&self) -> Vec { @@ -228,14 +310,28 @@ impl ProtoNetwork { info!("Order {order:?}"); self.nodes = order .iter() - .map(|id| { - let mut node = self.nodes.swap_remove(self.nodes.iter().position(|(test_id, _)| test_id == id).unwrap()).1; - node.map_ids(|id| *lookup.get(&id).unwrap()); - (*lookup.get(id).unwrap(), node) + .enumerate() + .map(|(pos, id)| { + let node = self.nodes.swap_remove(self.nodes.iter().position(|(test_id, _)| test_id == id).unwrap()).1; + (pos as NodeId, node) }) .collect(); + self.replace_node_references(&lookup); assert_eq!(order.len(), self.nodes.len()); } + + fn replace_node_references(&mut self, lookup: &HashMap) { + self.nodes.iter_mut().for_each(|(sid, node)| { + node.map_ids(|id| *lookup.get(&id).expect("node not found in lookup table")); + }); + self.inputs = self.inputs.iter().map(|id| *lookup.get(id).unwrap()).collect(); + self.output = *lookup.get(&self.output).unwrap(); + } + + fn replace_ids_with_lookup(&mut self, lookup: HashMap) { + self.nodes.iter_mut().for_each(|(id, _)| *id = *lookup.get(id).unwrap()); + self.replace_node_references(&lookup); + } } #[cfg(test)] @@ -246,6 +342,51 @@ mod test { #[test] fn topological_sort() { + let construction_network = test_network(); + let sorted = construction_network.topological_sort(); + + println!("{:#?}", sorted); + assert_eq!(sorted, vec![14, 10, 11, 1]); + } + + #[test] + fn id_reordering() { + let mut construction_network = test_network(); + construction_network.reorder_ids(); + let sorted = construction_network.topological_sort(); + println!("nodes: {:#?}", construction_network.nodes); + assert_eq!(sorted, vec![0, 1, 2, 3]); + let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect(); + println!("{:#?}", ids); + println!("nodes: {:#?}", construction_network.nodes); + assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value"); + assert_eq!(ids, vec![0, 1, 2, 3]); + } + + #[test] + fn id_reordering_idempotent() { + let mut construction_network = test_network(); + construction_network.reorder_ids(); + construction_network.reorder_ids(); + let sorted = construction_network.topological_sort(); + assert_eq!(sorted, vec![0, 1, 2, 3]); + let ids: Vec<_> = construction_network.nodes.iter().map(|(id, _)| *id).collect(); + println!("{:#?}", ids); + assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value"); + assert_eq!(ids, vec![0, 1, 2, 3]); + } + + #[test] + fn input_resolution() { + let mut construction_network = test_network(); + construction_network.resolve_inputs(); + println!("{:#?}", construction_network); + assert_eq!(construction_network.nodes[0].1.identifier.name.as_ref(), "value"); + assert_eq!(construction_network.nodes.len(), 6); + assert_eq!(construction_network.nodes[5].1.construction_args, ConstructionArgs::Nodes(vec![3, 4])); + } + + fn test_network() -> ProtoNetwork { let construction_network = ProtoNetwork { inputs: vec![10], output: 1, @@ -294,9 +435,6 @@ mod test { .into_iter() .collect(), }; - let sorted = construction_network.topological_sort(); - - println!("{:#?}", sorted); - assert_eq!(sorted, vec![14, 10, 11, 1]); + construction_network } } diff --git a/node-graph/gstd/Cargo.toml b/node-graph/gstd/Cargo.toml index fdb5d350d..014458668 100644 --- a/node-graph/gstd/Cargo.toml +++ b/node-graph/gstd/Cargo.toml @@ -15,7 +15,7 @@ default = ["derive", "memoization"] [dependencies] -graphene-core = {path = "../gcore", features = ["async", "std"]} +graphene-core = {path = "../gcore", features = ["async", "std"], default-features = false} borrow_stack = {path = "../borrow_stack"} dyn-any = {path = "../../libraries/dyn-any", features = ["derive"]} graph-proc-macros = {path = "../proc-macro", optional = true} diff --git a/node-graph/gstd/src/lib.rs b/node-graph/gstd/src/lib.rs index 04836cd45..f03914236 100644 --- a/node-graph/gstd/src/lib.rs +++ b/node-graph/gstd/src/lib.rs @@ -14,99 +14,3 @@ pub mod vector; pub mod any; pub use graphene_core::*; - -use quote::quote; -use syn::{Expr, ExprPath, Type}; - -/// Given a Node call tree, construct a function -/// that takes an input tuple and evaluates the call graph -/// on the gpu an fn node is constructed that takes a value -/// node as input -pub struct NodeGraph { - /// Collection of nodes with their corresponding inputs. - /// The first node always always has to be an Input Node. - pub nodes: Vec, - pub output: Type, - pub input: Type, -} - -pub enum NodeKind { - Value(Expr), - Input, - Node(ExprPath, Vec), -} - -impl NodeGraph { - pub fn serialize_function(&self) -> proc_macro2::TokenStream { - let output_type = &self.output; - let input_type = &self.input; - - fn nid(id: &usize) -> syn::Ident { - let str = format!("n{id}"); - syn::Ident::new(str.as_str(), proc_macro2::Span::call_site()) - } - let mut nodes = Vec::new(); - for (ref id, node) in self.nodes.iter().enumerate() { - let id = nid(id).clone(); - let line = match node { - NodeKind::Value(val) => { - quote! {let #id = graphene_core::value::ValueNode::new(#val);} - } - NodeKind::Node(node, ids) => { - let ids = ids.iter().map(nid).collect::>(); - quote! {let #id = #node::new((#(&#ids),*));} - } - NodeKind::Input => { - quote! { let n0 = graphene_core::value::ValueNode::new(input);} - } - }; - nodes.push(line) - } - let last_id = self.nodes.len() - 1; - let last_id = nid(&last_id); - let ret = quote! { #last_id.eval() }; - let function = quote! { - fn node_graph(input: #input_type) -> #output_type { - #(#nodes)* - #ret - } - }; - function - } - pub fn serialize_gpu(&self, name: &str) -> proc_macro2::TokenStream { - let function = self.serialize_function(); - let output_type = &self.output; - let input_type = &self.input; - - quote! { - #[cfg(target_arch = "spirv")] - pub mod gpu { - //#![deny(warnings)] - #[repr(C)] - pub struct PushConsts { - n: u32, - node: u32, - } - use super::*; - - use spirv_std::glam::UVec3; - - #[allow(unused)] - #[spirv(compute(threads(64)))] - pub fn #name( - #[spirv(global_invocation_id)] global_id: UVec3, - #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[#input_type], - #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [#output_type], - #[spirv(push_constant)] push_consts: &PushConsts, - ) { - #function - let gid = global_id.x as usize; - // Only process up to n, which is the length of the buffers. - if global_id.x < push_consts.n { - y[gid] = node_graph(a[gid]); - } - } - } - } - } -} diff --git a/node-graph/gstd/src/main.rs b/node-graph/gstd/src/main.rs index 5eb05960d..fa4165088 100644 --- a/node-graph/gstd/src/main.rs +++ b/node-graph/gstd/src/main.rs @@ -89,10 +89,8 @@ mod mul { // } fn main() { - use graphene_std::*; - use quote::quote; // use syn::parse::Parse; - let nodes = vec![ + /*let nodes = vec![ NodeKind::Input, NodeKind::Value(syn::parse_quote!(1u32)), NodeKind::Node(syn::parse_quote!(graphene_core::ops::AddNode), vec![0, 0]), @@ -105,7 +103,7 @@ fn main() { nodes, input: syn::Type::Verbatim(quote! {u32}), output: syn::Type::Verbatim(quote! {u32}), - }; + };*/ //let pretty = pretty_token_stream::Pretty::new(nodegraph.serialize_gpu("add")); //pretty.print();