From 1516d864f3ff3cf2fb413668f4814e0de47fb727 Mon Sep 17 00:00:00 2001 From: khyperia Date: Fri, 9 Oct 2020 17:22:07 +0200 Subject: [PATCH] First try at spirv-builder --- .gitignore | 2 +- Cargo.lock | 1037 +++++++++++++++- Cargo.toml | 4 +- examples/example-runner/Cargo.toml | 14 + examples/example-runner/build.rs | 8 + examples/example-runner/src/main.rs | 1076 +++++++++++++++++ examples/example-runner/src/vert.spv | Bin 0 -> 852 bytes examples/example-shader/Cargo.lock | 12 + examples/example-shader/Cargo.toml | 15 + examples/example-shader/src/lib.rs | 17 + rustc_codegen_spirv/build_libcore_test.bat | 9 - rustc_codegen_spirv/build_libcore_test.sh | 13 - .../build_libcore_test/.gitignore | 2 - .../build_libcore_test/Cargo.toml | 13 - .../build_libcore_test/src/lib.rs | 28 - .../run_libcore_test/.gitignore | 2 - .../run_libcore_test/Cargo.toml | 10 - .../run_libcore_test/src/main.rs | 80 -- rustc_codegen_spirv/src/builder/mod.rs | 5 +- rustc_codegen_spirv/tests/compile_and_val.rs | 36 - rustc_codegen_spirv/setup.bat => setup.bat | 0 rustc_codegen_spirv/setup.sh => setup.sh | 0 spirv-builder/Cargo.toml | 11 + spirv-builder/src/lib.rs | 103 ++ 24 files changed, 2275 insertions(+), 222 deletions(-) create mode 100644 examples/example-runner/Cargo.toml create mode 100644 examples/example-runner/build.rs create mode 100644 examples/example-runner/src/main.rs create mode 100644 examples/example-runner/src/vert.spv create mode 100644 examples/example-shader/Cargo.lock create mode 100644 examples/example-shader/Cargo.toml create mode 100644 examples/example-shader/src/lib.rs delete mode 100644 rustc_codegen_spirv/build_libcore_test.bat delete mode 100755 rustc_codegen_spirv/build_libcore_test.sh delete mode 100644 rustc_codegen_spirv/build_libcore_test/.gitignore delete mode 100644 rustc_codegen_spirv/build_libcore_test/Cargo.toml delete mode 100644 rustc_codegen_spirv/build_libcore_test/src/lib.rs delete mode 100644 rustc_codegen_spirv/run_libcore_test/.gitignore delete mode 100644 rustc_codegen_spirv/run_libcore_test/Cargo.toml delete mode 100644 rustc_codegen_spirv/run_libcore_test/src/main.rs delete mode 100644 rustc_codegen_spirv/tests/compile_and_val.rs rename rustc_codegen_spirv/setup.bat => setup.bat (100%) rename rustc_codegen_spirv/setup.sh => setup.sh (100%) create mode 100644 spirv-builder/Cargo.toml create mode 100644 spirv-builder/src/lib.rs diff --git a/.gitignore b/.gitignore index ea8c4bf7f3..2f7896d1d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/target +target/ diff --git a/Cargo.lock b/Cargo.lock index 7ac3441379..47084d0223 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,20 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + [[package]] name = "aho-corasick" version = "0.7.13" @@ -9,6 +24,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "andrew" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +dependencies = [ + "bitflags 1.2.1", + "line_drawing", + "rusttype 0.7.9", + "walkdir", + "xdg", + "xml-rs", +] + +[[package]] +name = "android_glue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" + [[package]] name = "ansi_term" version = "0.11.0" @@ -18,36 +53,251 @@ dependencies = [ "winapi", ] +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +dependencies = [ + "num-traits 0.2.12", +] + +[[package]] +name = "ash" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c69a8137596e84c22d57f3da1b5de1d4230b1742a710091c85f4d7ce50f00f38" +dependencies = [ + "libloading", +] + +[[package]] +name = "ash-window" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905c4ca25f752e7ab3c3e8f2882625f876e4c3ea5feffbc83f81d697e043afd6" +dependencies = [ + "ash", + "raw-window-handle", + "raw-window-metal", +] + [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "backtrace" +version = "0.3.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f813291114c186a042350e787af10c26534601062603d888be110f59f85ef8fa" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bimap" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43806ad6cd3dec8ef84ac19f35a7b0075aee8c8a913ffc3a09191e6d7131e781" +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "byteorder" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" + [[package]] name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "cc" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" + [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.2.1", +] + +[[package]] +name = "cocoa" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54" +dependencies = [ + "bitflags 1.2.1", + "block", + "core-foundation 0.6.4", + "core-graphics 0.17.3", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8" +dependencies = [ + "bitflags 1.2.1", + "block", + "core-foundation 0.7.0", + "core-graphics 0.19.2", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" + +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys 0.6.2", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-graphics" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" +dependencies = [ + "bitflags 1.2.1", + "core-foundation 0.6.4", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags 1.2.1", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + [[package]] name = "ctor" version = "0.1.16" @@ -55,7 +305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484" dependencies = [ "quote 1.0.7", - "syn 1.0.41", + "syn 1.0.42", ] [[package]] @@ -78,6 +328,47 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +[[package]] +name = "dlib" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +dependencies = [ + "num-traits 0.1.43", +] + +[[package]] +name = "example-runner" +version = "0.1.0" +dependencies = [ + "ash", + "ash-window", + "image", + "spirv-builder", + "winit", +] + [[package]] name = "filetime" version = "0.2.12" @@ -90,13 +381,44 @@ dependencies = [ "winapi", ] +[[package]] +name = "flate2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423" +dependencies = [ + "libc", + "miniz-sys", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder", + "byteorder 1.3.4", ] [[package]] @@ -110,6 +432,77 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e41945ba23db3bf51b24756d73d81acb4f28d85c3dccc32c6fae904438c25f" +dependencies = [ + "color_quant", + "lzw", +] + +[[package]] +name = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "image" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76df2dce95fef56fd35dbc41c36e37b19aede703c6be7739e8b65d5788ffc728" +dependencies = [ + "byteorder 0.5.3", + "enum_primitive", + "gif", + "glob", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits 0.1.43", + "png", + "scoped_threadpool", +] + +[[package]] +name = "inflate" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb" + +[[package]] +name = "itoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" + +[[package]] +name = "jpeg-decoder" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3" +dependencies = [ + "byteorder 1.3.4", + "rayon", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -118,9 +511,67 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" + +[[package]] +name = "libloading" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2443d8f0478b16759158b2f66d525991a05491138bc05814ef52a250148ef4f9" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "line_drawing" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +dependencies = [ + "num-traits 0.2.12", +] + +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" @@ -128,6 +579,112 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz-sys" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +dependencies = [ + "bitflags 1.2.1", + "cc", + "cfg-if", + "libc", + "void", +] + +[[package]] +name = "num-bigint" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" +dependencies = [ + "num-integer", + "num-traits 0.2.12", + "rand 0.4.6", + "rustc-serialize", +] + +[[package]] +name = "num-integer" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" +dependencies = [ + "autocfg", + "num-traits 0.2.12", +] + +[[package]] +name = "num-iter" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.12", +] + +[[package]] +name = "num-rational" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits 0.2.12", + "rustc-serialize", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.12", +] + [[package]] name = "num-traits" version = "0.2.12" @@ -137,6 +694,40 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "object" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" + +[[package]] +name = "ordered-float" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" +dependencies = [ + "num-traits 0.2.12", +] + [[package]] name = "output_vt100" version = "0.1.2" @@ -146,6 +737,56 @@ dependencies = [ "winapi", ] +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" +dependencies = [ + "lock_api", + "parking_lot_core", + "rustc_version", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pkg-config" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" + +[[package]] +name = "png" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997" +dependencies = [ + "bitflags 0.7.0", + "flate2", + "inflate", + "num-iter", +] + [[package]] name = "ppv-lite86" version = "0.2.9" @@ -175,9 +816,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.21" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid 0.2.1", ] @@ -197,7 +838,20 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.21", + "proc-macro2 1.0.24", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", ] [[package]] @@ -209,7 +863,7 @@ dependencies = [ "getrandom", "libc", "rand_chacha", - "rand_core", + "rand_core 0.5.1", "rand_hc", ] @@ -220,9 +874,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -238,7 +907,62 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + +[[package]] +name = "raw-window-metal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0f43bdc87adef4ce827b07775c9e59716b52f369696e7fb4ec7c4acb4e20b1" +dependencies = [ + "cocoa 0.20.2", + "core-graphics 0.19.2", + "objc", + "raw-window-handle", +] + +[[package]] +name = "rayon" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", ] [[package]] @@ -281,7 +1005,7 @@ source = "git+https://github.com/gfx-rs/rspirv.git?rev=1addc7d33ae1460ffa683e2e6 dependencies = [ "derive_more", "fxhash", - "num-traits", + "num-traits 0.2.12", "spirv_headers", ] @@ -296,6 +1020,18 @@ dependencies = [ "topological-sort", ] +[[package]] +name = "rustc-demangle" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2610b7f643d18c87dff3b489950269617e6601a51f1f05aa5daefee36f64f0b" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" + [[package]] name = "rustc_codegen_spirv" version = "0.1.0" @@ -317,6 +1053,53 @@ dependencies = [ "semver", ] +[[package]] +name = "rusttype" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +dependencies = [ + "rusttype 0.8.3", +] + +[[package]] +name = "rusttype" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +dependencies = [ + "approx", + "ordered-float", + "stb_truetype", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "semver" version = "0.9.0" @@ -332,6 +1115,71 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "serde" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.42", +] + +[[package]] +name = "serde_json" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "smallvec" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ccb8c57049b2a34d2cc2b203fa785020ba0129d31920ef0d317430adaf748fa" +dependencies = [ + "andrew", + "bitflags 1.2.1", + "dlib", + "lazy_static", + "memmap", + "nix", + "wayland-client", + "wayland-commons", + "wayland-protocols", +] + +[[package]] +name = "spirv-builder" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "spirv-std" version = "0.1.0" @@ -341,8 +1189,17 @@ name = "spirv_headers" version = "1.5.0" source = "git+https://github.com/gfx-rs/rspirv.git?rev=1addc7d33ae1460ffa683e2e6311e466ac876c23#1addc7d33ae1460ffa683e2e6311e466ac876c23" dependencies = [ - "bitflags", - "num-traits", + "bitflags 1.2.1", + "num-traits 0.2.12", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +dependencies = [ + "byteorder 1.3.4", ] [[package]] @@ -358,11 +1215,11 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" dependencies = [ - "proc-macro2 1.0.21", + "proc-macro2 1.0.24", "quote 1.0.7", "unicode-xid 0.2.1", ] @@ -387,7 +1244,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if", "libc", - "rand", + "rand 0.7.3", "redox_syscall", "remove_dir_all", "winapi", @@ -395,22 +1252,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" +checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab" dependencies = [ - "proc-macro2 1.0.21", + "proc-macro2 1.0.24", "quote 1.0.7", - "syn 1.0.41", + "syn 1.0.42", ] [[package]] @@ -440,12 +1297,88 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wayland-client" +version = "0.21.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49963e5f9eeaf637bfcd1b9f0701c99fd5cd05225eb51035550d4272806f2713" +dependencies = [ + "bitflags 1.2.1", + "downcast-rs", + "libc", + "nix", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.21.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c08896768b667e1df195d88a62a53a2d1351a1ed96188be79c196b35bb32ec" +dependencies = [ + "nix", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.21.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afde2ea2a428eee6d7d2c8584fdbe8b82eee8b6c353e129a434cd6e07f42145" +dependencies = [ + "bitflags 1.2.1", + "wayland-client", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-scanner" +version = "0.21.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3828c568714507315ee425a9529edc4a4aa9901409e373e9e0027e7622b79e" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.21.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520ab0fd578017a0ee2206623ba9ef4afe5e8f23ca7b42f6acfba2f4e66b1628" +dependencies = [ + "dlib", + "lazy_static", +] + [[package]] name = "winapi" version = "0.3.9" @@ -462,12 +1395,58 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winit" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e96eb4bb472fa43e718e8fa4aef82f86cd9deac9483a1e1529230babdb394a8" +dependencies = [ + "android_glue", + "backtrace", + "bitflags 1.2.1", + "cocoa 0.18.5", + "core-foundation 0.6.4", + "core-graphics 0.17.3", + "lazy_static", + "libc", + "log", + "objc", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "smithay-client-toolkit", + "wayland-client", + "winapi", + "x11-dl", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +dependencies = [ + "lazy_static", + "libc", + "maybe-uninit", + "pkg-config", +] + [[package]] name = "xattr" version = "0.2.2" @@ -476,3 +1455,15 @@ checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" dependencies = [ "libc", ] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" + +[[package]] +name = "xml-rs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" diff --git a/Cargo.toml b/Cargo.toml index 1eede79974..6fb2e3ca24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,11 @@ [workspace] members = [ + "examples/example-runner", "rspirv-linker", "rustc_codegen_spirv", + "spirv-builder", "spirv-std", ] [patch.crates-io] -rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "1addc7d33ae1460ffa683e2e6311e466ac876c23" } \ No newline at end of file +rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "1addc7d33ae1460ffa683e2e6311e466ac876c23" } diff --git a/examples/example-runner/Cargo.toml b/examples/example-runner/Cargo.toml new file mode 100644 index 0000000000..5986f1ed54 --- /dev/null +++ b/examples/example-runner/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "example-runner" +version = "0.1.0" +authors = ["Embark "] +edition = "2018" + +[dependencies] +winit = "0.19.5" +image = "0.10.4" +ash = "0.31" +ash-window = "0.5" + +[build-dependencies] +spirv-builder = { path = "../../spirv-builder" } diff --git a/examples/example-runner/build.rs b/examples/example-runner/build.rs new file mode 100644 index 0000000000..26889037b5 --- /dev/null +++ b/examples/example-runner/build.rs @@ -0,0 +1,8 @@ +use spirv_builder::build_spirv; +use std::error::Error; + +fn main() -> Result<(), Box> { + // This will set the env var `example-shader.spv` to a spir-v file that can be include!()'d + build_spirv("../../rustc_codegen_spirv", "../example-shader")?; + Ok(()) +} diff --git a/examples/example-runner/src/main.rs b/examples/example-runner/src/main.rs new file mode 100644 index 0000000000..3b214e35b9 --- /dev/null +++ b/examples/example-runner/src/main.rs @@ -0,0 +1,1076 @@ +// This file is copied pretty directly from +// https://github.com/MaikKlein/ash/blob/master/examples/src/bin/triangle.rs +// with the only major differences being +// 1) the minimum vulkan version bumped from v1.0 to v1.1 +// 2) the path to the vertex shader is env!("example_shader.spv"), i.e. +// let vertex_shader_file = include_bytes!(env!("example_shader.spv")); + +use ash::extensions::ext::DebugUtils; +use ash::extensions::khr::{Surface, Swapchain}; +use ash::util::*; +use ash::version::{DeviceV1_0, EntryV1_0, InstanceV1_0}; +use ash::{vk, Device, Entry, Instance}; +use std::borrow::Cow; +use std::cell::RefCell; +use std::default::Default; +use std::ffi::{CStr, CString}; +use std::io::Cursor; +use std::mem; +use std::mem::align_of; +use std::ops::Drop; + +// Simple offset_of macro akin to C++ offsetof +#[macro_export] +macro_rules! offset_of { + ($base:path, $field:ident) => {{ + #[allow(unused_unsafe)] + unsafe { + let b: $base = mem::zeroed(); + (&b.$field as *const _ as isize) - (&b as *const _ as isize) + } + }}; +} +/// Helper function for submitting command buffers. Immediately waits for the fence before the command buffer +/// is executed. That way we can delay the waiting for the fences by 1 frame which is good for performance. +/// Make sure to create the fence in a signaled state on the first use. +#[allow(clippy::too_many_arguments)] +pub fn record_submit_commandbuffer( + device: &D, + command_buffer: vk::CommandBuffer, + command_buffer_reuse_fence: vk::Fence, + submit_queue: vk::Queue, + wait_mask: &[vk::PipelineStageFlags], + wait_semaphores: &[vk::Semaphore], + signal_semaphores: &[vk::Semaphore], + f: F, +) { + unsafe { + device + .wait_for_fences(&[command_buffer_reuse_fence], true, std::u64::MAX) + .expect("Wait for fence failed."); + + device + .reset_fences(&[command_buffer_reuse_fence]) + .expect("Reset fences failed."); + + device + .reset_command_buffer( + command_buffer, + vk::CommandBufferResetFlags::RELEASE_RESOURCES, + ) + .expect("Reset command buffer failed."); + + let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder() + .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); + + device + .begin_command_buffer(command_buffer, &command_buffer_begin_info) + .expect("Begin commandbuffer"); + f(device, command_buffer); + device + .end_command_buffer(command_buffer) + .expect("End commandbuffer"); + + let command_buffers = vec![command_buffer]; + + let submit_info = vk::SubmitInfo::builder() + .wait_semaphores(wait_semaphores) + .wait_dst_stage_mask(wait_mask) + .command_buffers(&command_buffers) + .signal_semaphores(signal_semaphores); + + device + .queue_submit( + submit_queue, + &[submit_info.build()], + command_buffer_reuse_fence, + ) + .expect("queue submit failed."); + } +} + +unsafe extern "system" fn vulkan_debug_callback( + message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, + message_type: vk::DebugUtilsMessageTypeFlagsEXT, + p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, + _user_data: *mut std::os::raw::c_void, +) -> vk::Bool32 { + let callback_data = *p_callback_data; + let message_id_number: i32 = callback_data.message_id_number as i32; + + let message_id_name = if callback_data.p_message_id_name.is_null() { + Cow::from("") + } else { + CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() + }; + + let message = if callback_data.p_message.is_null() { + Cow::from("") + } else { + CStr::from_ptr(callback_data.p_message).to_string_lossy() + }; + + println!( + "{:?}:\n{:?} [{} ({})] : {}\n", + message_severity, + message_type, + message_id_name, + &message_id_number.to_string(), + message, + ); + + vk::FALSE +} + +pub fn find_memorytype_index( + memory_req: &vk::MemoryRequirements, + memory_prop: &vk::PhysicalDeviceMemoryProperties, + flags: vk::MemoryPropertyFlags, +) -> Option { + // Try to find an exactly matching memory flag + let best_suitable_index = + find_memorytype_index_f(memory_req, memory_prop, flags, |property_flags, flags| { + property_flags == flags + }); + if best_suitable_index.is_some() { + return best_suitable_index; + } + // Otherwise find a memory flag that works + find_memorytype_index_f(memory_req, memory_prop, flags, |property_flags, flags| { + property_flags & flags == flags + }) +} + +pub fn find_memorytype_index_f bool>( + memory_req: &vk::MemoryRequirements, + memory_prop: &vk::PhysicalDeviceMemoryProperties, + flags: vk::MemoryPropertyFlags, + f: F, +) -> Option { + let mut memory_type_bits = memory_req.memory_type_bits; + for (index, ref memory_type) in memory_prop.memory_types.iter().enumerate() { + if memory_type_bits & 1 == 1 && f(memory_type.property_flags, flags) { + return Some(index as u32); + } + memory_type_bits >>= 1; + } + None +} + +pub struct ExampleBase { + pub entry: Entry, + pub instance: Instance, + pub device: Device, + pub surface_loader: Surface, + pub swapchain_loader: Swapchain, + pub debug_utils_loader: DebugUtils, + pub window: winit::Window, + pub events_loop: RefCell, + pub debug_call_back: vk::DebugUtilsMessengerEXT, + + pub pdevice: vk::PhysicalDevice, + pub device_memory_properties: vk::PhysicalDeviceMemoryProperties, + pub queue_family_index: u32, + pub present_queue: vk::Queue, + + pub surface: vk::SurfaceKHR, + pub surface_format: vk::SurfaceFormatKHR, + pub surface_resolution: vk::Extent2D, + + pub swapchain: vk::SwapchainKHR, + pub present_images: Vec, + pub present_image_views: Vec, + + pub pool: vk::CommandPool, + pub draw_command_buffer: vk::CommandBuffer, + pub setup_command_buffer: vk::CommandBuffer, + + pub depth_image: vk::Image, + pub depth_image_view: vk::ImageView, + pub depth_image_memory: vk::DeviceMemory, + + pub present_complete_semaphore: vk::Semaphore, + pub rendering_complete_semaphore: vk::Semaphore, + + pub draw_commands_reuse_fence: vk::Fence, + pub setup_commands_reuse_fence: vk::Fence, +} + +impl ExampleBase { + pub fn render_loop(&self, f: F) { + use winit::*; + self.events_loop.borrow_mut().run_forever(|event| { + f(); + match event { + Event::WindowEvent { event, .. } => match event { + WindowEvent::KeyboardInput { input, .. } => { + if let Some(VirtualKeyCode::Escape) = input.virtual_keycode { + ControlFlow::Break + } else { + ControlFlow::Continue + } + } + WindowEvent::CloseRequested => winit::ControlFlow::Break, + _ => ControlFlow::Continue, + }, + _ => ControlFlow::Continue, + } + }); + } + + pub fn new(window_width: u32, window_height: u32) -> Self { + unsafe { + let events_loop = winit::EventsLoop::new(); + let window = winit::WindowBuilder::new() + .with_title("Ash - Example") + .with_dimensions(winit::dpi::LogicalSize::new( + f64::from(window_width), + f64::from(window_height), + )) + .build(&events_loop) + .unwrap(); + let entry = Entry::new().unwrap(); + let app_name = CString::new("VulkanTriangle").unwrap(); + + let layer_names = [CString::new("VK_LAYER_KHRONOS_validation").unwrap()]; + let layers_names_raw: Vec<*const i8> = layer_names + .iter() + .map(|raw_name| raw_name.as_ptr()) + .collect(); + + let surface_extensions = ash_window::enumerate_required_extensions(&window).unwrap(); + let mut extension_names_raw = surface_extensions + .iter() + .map(|ext| ext.as_ptr()) + .collect::>(); + extension_names_raw.push(DebugUtils::name().as_ptr()); + + let appinfo = vk::ApplicationInfo::builder() + .application_name(&app_name) + .application_version(0) + .engine_name(&app_name) + .engine_version(0) + .api_version(vk::make_version(1, 1, 0)); + + let create_info = vk::InstanceCreateInfo::builder() + .application_info(&appinfo) + .enabled_layer_names(&layers_names_raw) + .enabled_extension_names(&extension_names_raw); + + let instance: Instance = entry + .create_instance(&create_info, None) + .expect("Instance creation error"); + + let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder() + .message_severity( + vk::DebugUtilsMessageSeverityFlagsEXT::ERROR + | vk::DebugUtilsMessageSeverityFlagsEXT::WARNING + | vk::DebugUtilsMessageSeverityFlagsEXT::INFO, + ) + .message_type(vk::DebugUtilsMessageTypeFlagsEXT::all()) + .pfn_user_callback(Some(vulkan_debug_callback)); + + let debug_utils_loader = DebugUtils::new(&entry, &instance); + let debug_call_back = debug_utils_loader + .create_debug_utils_messenger(&debug_info, None) + .unwrap(); + let surface = ash_window::create_surface(&entry, &instance, &window, None).unwrap(); + let pdevices = instance + .enumerate_physical_devices() + .expect("Physical device error"); + let surface_loader = Surface::new(&entry, &instance); + let (pdevice, queue_family_index) = pdevices + .iter() + .map(|pdevice| { + instance + .get_physical_device_queue_family_properties(*pdevice) + .iter() + .enumerate() + .filter_map(|(index, ref info)| { + let supports_graphic_and_surface = + info.queue_flags.contains(vk::QueueFlags::GRAPHICS) + && surface_loader + .get_physical_device_surface_support( + *pdevice, + index as u32, + surface, + ) + .unwrap(); + if supports_graphic_and_surface { + Some((*pdevice, index)) + } else { + None + } + }) + .next() + }) + .filter_map(|v| v) + .next() + .expect("Couldn't find suitable device."); + let queue_family_index = queue_family_index as u32; + let device_extension_names_raw = [Swapchain::name().as_ptr()]; + let features = vk::PhysicalDeviceFeatures { + shader_clip_distance: 1, + ..Default::default() + }; + let priorities = [1.0]; + + let queue_info = [vk::DeviceQueueCreateInfo::builder() + .queue_family_index(queue_family_index) + .queue_priorities(&priorities) + .build()]; + + let device_create_info = vk::DeviceCreateInfo::builder() + .queue_create_infos(&queue_info) + .enabled_extension_names(&device_extension_names_raw) + .enabled_features(&features); + + let device: Device = instance + .create_device(pdevice, &device_create_info, None) + .unwrap(); + + let present_queue = device.get_device_queue(queue_family_index as u32, 0); + + let surface_formats = surface_loader + .get_physical_device_surface_formats(pdevice, surface) + .unwrap(); + let surface_format = surface_formats + .iter() + .map(|sfmt| match sfmt.format { + vk::Format::UNDEFINED => vk::SurfaceFormatKHR { + format: vk::Format::B8G8R8_UNORM, + color_space: sfmt.color_space, + }, + _ => *sfmt, + }) + .next() + .expect("Unable to find suitable surface format."); + let surface_capabilities = surface_loader + .get_physical_device_surface_capabilities(pdevice, surface) + .unwrap(); + let mut desired_image_count = surface_capabilities.min_image_count + 1; + if surface_capabilities.max_image_count > 0 + && desired_image_count > surface_capabilities.max_image_count + { + desired_image_count = surface_capabilities.max_image_count; + } + let surface_resolution = match surface_capabilities.current_extent.width { + std::u32::MAX => vk::Extent2D { + width: window_width, + height: window_height, + }, + _ => surface_capabilities.current_extent, + }; + let pre_transform = if surface_capabilities + .supported_transforms + .contains(vk::SurfaceTransformFlagsKHR::IDENTITY) + { + vk::SurfaceTransformFlagsKHR::IDENTITY + } else { + surface_capabilities.current_transform + }; + let present_modes = surface_loader + .get_physical_device_surface_present_modes(pdevice, surface) + .unwrap(); + let present_mode = present_modes + .iter() + .cloned() + .find(|&mode| mode == vk::PresentModeKHR::MAILBOX) + .unwrap_or(vk::PresentModeKHR::FIFO); + let swapchain_loader = Swapchain::new(&instance, &device); + + let swapchain_create_info = vk::SwapchainCreateInfoKHR::builder() + .surface(surface) + .min_image_count(desired_image_count) + .image_color_space(surface_format.color_space) + .image_format(surface_format.format) + .image_extent(surface_resolution) + .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT) + .image_sharing_mode(vk::SharingMode::EXCLUSIVE) + .pre_transform(pre_transform) + .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) + .present_mode(present_mode) + .clipped(true) + .image_array_layers(1); + + let swapchain = swapchain_loader + .create_swapchain(&swapchain_create_info, None) + .unwrap(); + + let pool_create_info = vk::CommandPoolCreateInfo::builder() + .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER) + .queue_family_index(queue_family_index); + + let pool = device.create_command_pool(&pool_create_info, None).unwrap(); + + let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::builder() + .command_buffer_count(2) + .command_pool(pool) + .level(vk::CommandBufferLevel::PRIMARY); + + let command_buffers = device + .allocate_command_buffers(&command_buffer_allocate_info) + .unwrap(); + let setup_command_buffer = command_buffers[0]; + let draw_command_buffer = command_buffers[1]; + + let present_images = swapchain_loader.get_swapchain_images(swapchain).unwrap(); + let present_image_views: Vec = present_images + .iter() + .map(|&image| { + let create_view_info = vk::ImageViewCreateInfo::builder() + .view_type(vk::ImageViewType::TYPE_2D) + .format(surface_format.format) + .components(vk::ComponentMapping { + r: vk::ComponentSwizzle::R, + g: vk::ComponentSwizzle::G, + b: vk::ComponentSwizzle::B, + a: vk::ComponentSwizzle::A, + }) + .subresource_range(vk::ImageSubresourceRange { + aspect_mask: vk::ImageAspectFlags::COLOR, + base_mip_level: 0, + level_count: 1, + base_array_layer: 0, + layer_count: 1, + }) + .image(image); + device.create_image_view(&create_view_info, None).unwrap() + }) + .collect(); + let device_memory_properties = instance.get_physical_device_memory_properties(pdevice); + let depth_image_create_info = vk::ImageCreateInfo::builder() + .image_type(vk::ImageType::TYPE_2D) + .format(vk::Format::D16_UNORM) + .extent(vk::Extent3D { + width: surface_resolution.width, + height: surface_resolution.height, + depth: 1, + }) + .mip_levels(1) + .array_layers(1) + .samples(vk::SampleCountFlags::TYPE_1) + .tiling(vk::ImageTiling::OPTIMAL) + .usage(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + + let depth_image = device.create_image(&depth_image_create_info, None).unwrap(); + let depth_image_memory_req = device.get_image_memory_requirements(depth_image); + let depth_image_memory_index = find_memorytype_index( + &depth_image_memory_req, + &device_memory_properties, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + ) + .expect("Unable to find suitable memory index for depth image."); + + let depth_image_allocate_info = vk::MemoryAllocateInfo::builder() + .allocation_size(depth_image_memory_req.size) + .memory_type_index(depth_image_memory_index); + + let depth_image_memory = device + .allocate_memory(&depth_image_allocate_info, None) + .unwrap(); + + device + .bind_image_memory(depth_image, depth_image_memory, 0) + .expect("Unable to bind depth image memory"); + + let fence_create_info = + vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED); + + let draw_commands_reuse_fence = device + .create_fence(&fence_create_info, None) + .expect("Create fence failed."); + let setup_commands_reuse_fence = device + .create_fence(&fence_create_info, None) + .expect("Create fence failed."); + + record_submit_commandbuffer( + &device, + setup_command_buffer, + setup_commands_reuse_fence, + present_queue, + &[], + &[], + &[], + |device, setup_command_buffer| { + let layout_transition_barriers = vk::ImageMemoryBarrier::builder() + .image(depth_image) + .dst_access_mask( + vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ + | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE, + ) + .new_layout(vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + .old_layout(vk::ImageLayout::UNDEFINED) + .subresource_range( + vk::ImageSubresourceRange::builder() + .aspect_mask(vk::ImageAspectFlags::DEPTH) + .layer_count(1) + .level_count(1) + .build(), + ); + + device.cmd_pipeline_barrier( + setup_command_buffer, + vk::PipelineStageFlags::BOTTOM_OF_PIPE, + vk::PipelineStageFlags::LATE_FRAGMENT_TESTS, + vk::DependencyFlags::empty(), + &[], + &[], + &[layout_transition_barriers.build()], + ); + }, + ); + + let depth_image_view_info = vk::ImageViewCreateInfo::builder() + .subresource_range( + vk::ImageSubresourceRange::builder() + .aspect_mask(vk::ImageAspectFlags::DEPTH) + .level_count(1) + .layer_count(1) + .build(), + ) + .image(depth_image) + .format(depth_image_create_info.format) + .view_type(vk::ImageViewType::TYPE_2D); + + let depth_image_view = device + .create_image_view(&depth_image_view_info, None) + .unwrap(); + + let semaphore_create_info = vk::SemaphoreCreateInfo::default(); + + let present_complete_semaphore = device + .create_semaphore(&semaphore_create_info, None) + .unwrap(); + let rendering_complete_semaphore = device + .create_semaphore(&semaphore_create_info, None) + .unwrap(); + + ExampleBase { + events_loop: RefCell::new(events_loop), + entry, + instance, + device, + queue_family_index, + pdevice, + device_memory_properties, + window, + surface_loader, + surface_format, + present_queue, + surface_resolution, + swapchain_loader, + swapchain, + present_images, + present_image_views, + pool, + draw_command_buffer, + setup_command_buffer, + depth_image, + depth_image_view, + present_complete_semaphore, + rendering_complete_semaphore, + draw_commands_reuse_fence, + setup_commands_reuse_fence, + surface, + debug_call_back, + debug_utils_loader, + depth_image_memory, + } + } + } +} + +impl Drop for ExampleBase { + fn drop(&mut self) { + unsafe { + self.device.device_wait_idle().unwrap(); + self.device + .destroy_semaphore(self.present_complete_semaphore, None); + self.device + .destroy_semaphore(self.rendering_complete_semaphore, None); + self.device + .destroy_fence(self.draw_commands_reuse_fence, None); + self.device + .destroy_fence(self.setup_commands_reuse_fence, None); + self.device.free_memory(self.depth_image_memory, None); + self.device.destroy_image_view(self.depth_image_view, None); + self.device.destroy_image(self.depth_image, None); + for &image_view in self.present_image_views.iter() { + self.device.destroy_image_view(image_view, None); + } + self.device.destroy_command_pool(self.pool, None); + self.swapchain_loader + .destroy_swapchain(self.swapchain, None); + self.device.destroy_device(None); + self.surface_loader.destroy_surface(self.surface, None); + self.debug_utils_loader + .destroy_debug_utils_messenger(self.debug_call_back, None); + self.instance.destroy_instance(None); + } + } +} + +#[derive(Clone, Debug, Copy)] +struct Vertex { + pos: [f32; 4], + color: [f32; 4], +} + +fn main() { + unsafe { + let base = ExampleBase::new(1920, 1080); + let renderpass_attachments = [ + vk::AttachmentDescription { + format: base.surface_format.format, + samples: vk::SampleCountFlags::TYPE_1, + load_op: vk::AttachmentLoadOp::CLEAR, + store_op: vk::AttachmentStoreOp::STORE, + final_layout: vk::ImageLayout::PRESENT_SRC_KHR, + ..Default::default() + }, + vk::AttachmentDescription { + format: vk::Format::D16_UNORM, + samples: vk::SampleCountFlags::TYPE_1, + load_op: vk::AttachmentLoadOp::CLEAR, + initial_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + final_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + ..Default::default() + }, + ]; + let color_attachment_refs = [vk::AttachmentReference { + attachment: 0, + layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + }]; + let depth_attachment_ref = vk::AttachmentReference { + attachment: 1, + layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + }; + let dependencies = [vk::SubpassDependency { + src_subpass: vk::SUBPASS_EXTERNAL, + src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, + dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_READ + | vk::AccessFlags::COLOR_ATTACHMENT_WRITE, + dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, + ..Default::default() + }]; + + let subpasses = [vk::SubpassDescription::builder() + .color_attachments(&color_attachment_refs) + .depth_stencil_attachment(&depth_attachment_ref) + .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS) + .build()]; + + let renderpass_create_info = vk::RenderPassCreateInfo::builder() + .attachments(&renderpass_attachments) + .subpasses(&subpasses) + .dependencies(&dependencies); + + let renderpass = base + .device + .create_render_pass(&renderpass_create_info, None) + .unwrap(); + + let framebuffers: Vec = base + .present_image_views + .iter() + .map(|&present_image_view| { + let framebuffer_attachments = [present_image_view, base.depth_image_view]; + let frame_buffer_create_info = vk::FramebufferCreateInfo::builder() + .render_pass(renderpass) + .attachments(&framebuffer_attachments) + .width(base.surface_resolution.width) + .height(base.surface_resolution.height) + .layers(1); + + base.device + .create_framebuffer(&frame_buffer_create_info, None) + .unwrap() + }) + .collect(); + + let index_buffer_data = [0u32, 1, 2]; + let index_buffer_info = vk::BufferCreateInfo::builder() + .size(std::mem::size_of_val(&index_buffer_data) as u64) + .usage(vk::BufferUsageFlags::INDEX_BUFFER) + .sharing_mode(vk::SharingMode::EXCLUSIVE); + + let index_buffer = base.device.create_buffer(&index_buffer_info, None).unwrap(); + let index_buffer_memory_req = base.device.get_buffer_memory_requirements(index_buffer); + let index_buffer_memory_index = find_memorytype_index( + &index_buffer_memory_req, + &base.device_memory_properties, + vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, + ) + .expect("Unable to find suitable memorytype for the index buffer."); + + let index_allocate_info = vk::MemoryAllocateInfo { + allocation_size: index_buffer_memory_req.size, + memory_type_index: index_buffer_memory_index, + ..Default::default() + }; + let index_buffer_memory = base + .device + .allocate_memory(&index_allocate_info, None) + .unwrap(); + let index_ptr = base + .device + .map_memory( + index_buffer_memory, + 0, + index_buffer_memory_req.size, + vk::MemoryMapFlags::empty(), + ) + .unwrap(); + let mut index_slice = Align::new( + index_ptr, + align_of::() as u64, + index_buffer_memory_req.size, + ); + index_slice.copy_from_slice(&index_buffer_data); + base.device.unmap_memory(index_buffer_memory); + base.device + .bind_buffer_memory(index_buffer, index_buffer_memory, 0) + .unwrap(); + + let vertex_input_buffer_info = vk::BufferCreateInfo { + size: 3 * std::mem::size_of::() as u64, + usage: vk::BufferUsageFlags::VERTEX_BUFFER, + sharing_mode: vk::SharingMode::EXCLUSIVE, + ..Default::default() + }; + + let vertex_input_buffer = base + .device + .create_buffer(&vertex_input_buffer_info, None) + .unwrap(); + + let vertex_input_buffer_memory_req = base + .device + .get_buffer_memory_requirements(vertex_input_buffer); + + let vertex_input_buffer_memory_index = find_memorytype_index( + &vertex_input_buffer_memory_req, + &base.device_memory_properties, + vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT, + ) + .expect("Unable to find suitable memorytype for the vertex buffer."); + + let vertex_buffer_allocate_info = vk::MemoryAllocateInfo { + allocation_size: vertex_input_buffer_memory_req.size, + memory_type_index: vertex_input_buffer_memory_index, + ..Default::default() + }; + + let vertex_input_buffer_memory = base + .device + .allocate_memory(&vertex_buffer_allocate_info, None) + .unwrap(); + + let vertices = [ + Vertex { + pos: [-1.0, 1.0, 0.0, 1.0], + color: [0.0, 1.0, 0.0, 1.0], + }, + Vertex { + pos: [1.0, 1.0, 0.0, 1.0], + color: [0.0, 0.0, 1.0, 1.0], + }, + Vertex { + pos: [0.0, -1.0, 0.0, 1.0], + color: [1.0, 0.0, 0.0, 1.0], + }, + ]; + + let vert_ptr = base + .device + .map_memory( + vertex_input_buffer_memory, + 0, + vertex_input_buffer_memory_req.size, + vk::MemoryMapFlags::empty(), + ) + .unwrap(); + + let mut vert_align = Align::new( + vert_ptr, + align_of::() as u64, + vertex_input_buffer_memory_req.size, + ); + vert_align.copy_from_slice(&vertices); + base.device.unmap_memory(vertex_input_buffer_memory); + base.device + .bind_buffer_memory(vertex_input_buffer, vertex_input_buffer_memory, 0) + .unwrap(); + let mut vertex_spv_file = Cursor::new(&include_bytes!("vert.spv")[..]); + let mut frag_spv_file = Cursor::new(&include_bytes!(env!("example_shader.spv"))[..]); + + let vertex_code = + read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file"); + let vertex_shader_info = vk::ShaderModuleCreateInfo::builder().code(&vertex_code); + + let frag_code = + read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file"); + let frag_shader_info = vk::ShaderModuleCreateInfo::builder().code(&frag_code); + + let vertex_shader_module = base + .device + .create_shader_module(&vertex_shader_info, None) + .expect("Vertex shader module error"); + + let fragment_shader_module = base + .device + .create_shader_module(&frag_shader_info, None) + .expect("Fragment shader module error"); + + let layout_create_info = vk::PipelineLayoutCreateInfo::default(); + + let pipeline_layout = base + .device + .create_pipeline_layout(&layout_create_info, None) + .unwrap(); + + let shader_entry_name = CString::new("main").unwrap(); + let shader_stage_create_infos = [ + vk::PipelineShaderStageCreateInfo { + module: vertex_shader_module, + p_name: shader_entry_name.as_ptr(), + stage: vk::ShaderStageFlags::VERTEX, + ..Default::default() + }, + vk::PipelineShaderStageCreateInfo { + s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO, + module: fragment_shader_module, + p_name: shader_entry_name.as_ptr(), + stage: vk::ShaderStageFlags::FRAGMENT, + ..Default::default() + }, + ]; + let vertex_input_binding_descriptions = [vk::VertexInputBindingDescription { + binding: 0, + stride: mem::size_of::() as u32, + input_rate: vk::VertexInputRate::VERTEX, + }]; + let vertex_input_attribute_descriptions = [ + vk::VertexInputAttributeDescription { + location: 0, + binding: 0, + format: vk::Format::R32G32B32A32_SFLOAT, + offset: offset_of!(Vertex, pos) as u32, + }, + vk::VertexInputAttributeDescription { + location: 1, + binding: 0, + format: vk::Format::R32G32B32A32_SFLOAT, + offset: offset_of!(Vertex, color) as u32, + }, + ]; + + let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo { + vertex_attribute_description_count: vertex_input_attribute_descriptions.len() as u32, + p_vertex_attribute_descriptions: vertex_input_attribute_descriptions.as_ptr(), + vertex_binding_description_count: vertex_input_binding_descriptions.len() as u32, + p_vertex_binding_descriptions: vertex_input_binding_descriptions.as_ptr(), + ..Default::default() + }; + let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { + topology: vk::PrimitiveTopology::TRIANGLE_LIST, + ..Default::default() + }; + let viewports = [vk::Viewport { + x: 0.0, + y: 0.0, + width: base.surface_resolution.width as f32, + height: base.surface_resolution.height as f32, + min_depth: 0.0, + max_depth: 1.0, + }]; + let scissors = [vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: base.surface_resolution, + }]; + let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() + .scissors(&scissors) + .viewports(&viewports); + + let rasterization_info = vk::PipelineRasterizationStateCreateInfo { + front_face: vk::FrontFace::COUNTER_CLOCKWISE, + line_width: 1.0, + polygon_mode: vk::PolygonMode::FILL, + ..Default::default() + }; + let multisample_state_info = vk::PipelineMultisampleStateCreateInfo { + rasterization_samples: vk::SampleCountFlags::TYPE_1, + ..Default::default() + }; + let noop_stencil_state = vk::StencilOpState { + fail_op: vk::StencilOp::KEEP, + pass_op: vk::StencilOp::KEEP, + depth_fail_op: vk::StencilOp::KEEP, + compare_op: vk::CompareOp::ALWAYS, + ..Default::default() + }; + let depth_state_info = vk::PipelineDepthStencilStateCreateInfo { + depth_test_enable: 1, + depth_write_enable: 1, + depth_compare_op: vk::CompareOp::LESS_OR_EQUAL, + front: noop_stencil_state, + back: noop_stencil_state, + max_depth_bounds: 1.0, + ..Default::default() + }; + let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { + blend_enable: 0, + src_color_blend_factor: vk::BlendFactor::SRC_COLOR, + dst_color_blend_factor: vk::BlendFactor::ONE_MINUS_DST_COLOR, + color_blend_op: vk::BlendOp::ADD, + src_alpha_blend_factor: vk::BlendFactor::ZERO, + dst_alpha_blend_factor: vk::BlendFactor::ZERO, + alpha_blend_op: vk::BlendOp::ADD, + color_write_mask: vk::ColorComponentFlags::all(), + }]; + let color_blend_state = vk::PipelineColorBlendStateCreateInfo::builder() + .logic_op(vk::LogicOp::CLEAR) + .attachments(&color_blend_attachment_states); + + let dynamic_state = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; + let dynamic_state_info = + vk::PipelineDynamicStateCreateInfo::builder().dynamic_states(&dynamic_state); + + let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::builder() + .stages(&shader_stage_create_infos) + .vertex_input_state(&vertex_input_state_info) + .input_assembly_state(&vertex_input_assembly_state_info) + .viewport_state(&viewport_state_info) + .rasterization_state(&rasterization_info) + .multisample_state(&multisample_state_info) + .depth_stencil_state(&depth_state_info) + .color_blend_state(&color_blend_state) + .dynamic_state(&dynamic_state_info) + .layout(pipeline_layout) + .render_pass(renderpass); + + let graphics_pipelines = base + .device + .create_graphics_pipelines( + vk::PipelineCache::null(), + &[graphic_pipeline_info.build()], + None, + ) + .expect("Unable to create graphics pipeline"); + + let graphic_pipeline = graphics_pipelines[0]; + + base.render_loop(|| { + let (present_index, _) = base + .swapchain_loader + .acquire_next_image( + base.swapchain, + std::u64::MAX, + base.present_complete_semaphore, + vk::Fence::null(), + ) + .unwrap(); + let clear_values = [ + vk::ClearValue { + color: vk::ClearColorValue { + float32: [0.0, 0.0, 0.0, 0.0], + }, + }, + vk::ClearValue { + depth_stencil: vk::ClearDepthStencilValue { + depth: 1.0, + stencil: 0, + }, + }, + ]; + + let render_pass_begin_info = vk::RenderPassBeginInfo::builder() + .render_pass(renderpass) + .framebuffer(framebuffers[present_index as usize]) + .render_area(vk::Rect2D { + offset: vk::Offset2D { x: 0, y: 0 }, + extent: base.surface_resolution, + }) + .clear_values(&clear_values); + + record_submit_commandbuffer( + &base.device, + base.draw_command_buffer, + base.draw_commands_reuse_fence, + base.present_queue, + &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT], + &[base.present_complete_semaphore], + &[base.rendering_complete_semaphore], + |device, draw_command_buffer| { + device.cmd_begin_render_pass( + draw_command_buffer, + &render_pass_begin_info, + vk::SubpassContents::INLINE, + ); + device.cmd_bind_pipeline( + draw_command_buffer, + vk::PipelineBindPoint::GRAPHICS, + graphic_pipeline, + ); + device.cmd_set_viewport(draw_command_buffer, 0, &viewports); + device.cmd_set_scissor(draw_command_buffer, 0, &scissors); + device.cmd_bind_vertex_buffers( + draw_command_buffer, + 0, + &[vertex_input_buffer], + &[0], + ); + device.cmd_bind_index_buffer( + draw_command_buffer, + index_buffer, + 0, + vk::IndexType::UINT32, + ); + device.cmd_draw_indexed( + draw_command_buffer, + index_buffer_data.len() as u32, + 1, + 0, + 0, + 1, + ); + // Or draw without the index buffer + // device.cmd_draw(draw_command_buffer, 3, 1, 0, 0); + device.cmd_end_render_pass(draw_command_buffer); + }, + ); + //let mut present_info_err = mem::zeroed(); + let wait_semaphors = [base.rendering_complete_semaphore]; + let swapchains = [base.swapchain]; + let image_indices = [present_index]; + let present_info = vk::PresentInfoKHR::builder() + .wait_semaphores(&wait_semaphors) // &base.rendering_complete_semaphore) + .swapchains(&swapchains) + .image_indices(&image_indices); + + base.swapchain_loader + .queue_present(base.present_queue, &present_info) + .unwrap(); + }); + + base.device.device_wait_idle().unwrap(); + for pipeline in graphics_pipelines { + base.device.destroy_pipeline(pipeline, None); + } + base.device.destroy_pipeline_layout(pipeline_layout, None); + base.device + .destroy_shader_module(vertex_shader_module, None); + base.device + .destroy_shader_module(fragment_shader_module, None); + base.device.free_memory(index_buffer_memory, None); + base.device.destroy_buffer(index_buffer, None); + base.device.free_memory(vertex_input_buffer_memory, None); + base.device.destroy_buffer(vertex_input_buffer, None); + for framebuffer in framebuffers { + base.device.destroy_framebuffer(framebuffer, None); + } + base.device.destroy_render_pass(renderpass, None); + } +} diff --git a/examples/example-runner/src/vert.spv b/examples/example-runner/src/vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..8d8a6f1d53465143793f9490531950e43059cbf1 GIT binary patch literal 852 zcmY+COH0E*6otp858v;$E~Hdk3L;WP5CtC)7hQ;g+YsvzqcsUh1o2n+bKMA@Z`y!P zxw&)BJ(+XwG+u4DWz39zvu4Xo)|#ma8?#`VF8jm#;eJs*?GKI)P%InI3DK;WIk&It z`4+|r0A@k4u4pSf{c6fzdZDhWKMXGJE`!2mVIGz?D4xS7n+NIRiyf84e~n6U5(VQh ziQdD=27|+cEF8U>hEDqH3C1@KM(H@sU7a2#$Ot#hs&F(8Zf*Wx^U{6@ikhsFrLmbdZ32KnlgUOMGs)UCpbJd zl=}+K!~?vkV4"] +edition = "2018" + +[lib] +crate-type = ["dylib"] + +[dependencies] +spirv-std = { path = "../../spirv-std" } + +# This crate is built specially by the example-runner crate, and so therefore +# should be excluded from the top-level `cargo build` etc. +[workspace] diff --git a/examples/example-shader/src/lib.rs b/examples/example-shader/src/lib.rs new file mode 100644 index 0000000000..cdff211306 --- /dev/null +++ b/examples/example-shader/src/lib.rs @@ -0,0 +1,17 @@ +#![no_std] +#![feature(register_attr)] +#![register_attr(spirv)] + +use core::panic::PanicInfo; +use spirv_std::{f32x4, Input, Output}; + +#[allow(unused_attributes)] +#[spirv(entry = "fragment")] +pub fn main(input: Input, mut output: Output) { + output.store(input.load()) +} + +#[panic_handler] +fn panic(_: &PanicInfo) -> ! { + loop {} +} diff --git a/rustc_codegen_spirv/build_libcore_test.bat b/rustc_codegen_spirv/build_libcore_test.bat deleted file mode 100644 index 674d23055c..0000000000 --- a/rustc_codegen_spirv/build_libcore_test.bat +++ /dev/null @@ -1,9 +0,0 @@ -setlocal -cargo build - -set RUSTFLAGS=-Zcodegen-backend=%cd%/../target/debug/rustc_codegen_spirv.dll - -pushd build_libcore_test -set SPIRV_VAL=1 -cargo build -Z build-std=core --target spirv-unknown-unknown --release -popd diff --git a/rustc_codegen_spirv/build_libcore_test.sh b/rustc_codegen_spirv/build_libcore_test.sh deleted file mode 100755 index caf18473b0..0000000000 --- a/rustc_codegen_spirv/build_libcore_test.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# exit on cmd failure -set -e - -# build rustc_codegen_spirv -cargo build - -export RUSTFLAGS="-Zcodegen-backend=$PWD/../target/debug/librustc_codegen_spirv.so" - -pushd build_libcore_test -SPIRV_VAL=${SPIRV_VAL-1} cargo build -Z build-std=core --target spirv-unknown-unknown --release -popd diff --git a/rustc_codegen_spirv/build_libcore_test/.gitignore b/rustc_codegen_spirv/build_libcore_test/.gitignore deleted file mode 100644 index e9e21997b1..0000000000 --- a/rustc_codegen_spirv/build_libcore_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -/Cargo.lock diff --git a/rustc_codegen_spirv/build_libcore_test/Cargo.toml b/rustc_codegen_spirv/build_libcore_test/Cargo.toml deleted file mode 100644 index 059841f6f1..0000000000 --- a/rustc_codegen_spirv/build_libcore_test/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "build_libcore_test" -version = "0.1.0" -authors = ["Ashley Hauck "] -edition = "2018" - -[lib] -crate-type = ["dylib"] - -[dependencies] -spirv-std = { path = "../../spirv-std" } - -[workspace] diff --git a/rustc_codegen_spirv/build_libcore_test/src/lib.rs b/rustc_codegen_spirv/build_libcore_test/src/lib.rs deleted file mode 100644 index 53da314ed1..0000000000 --- a/rustc_codegen_spirv/build_libcore_test/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![no_std] -#![feature(register_attr)] -#![register_attr(spirv)] - -use core::panic::PanicInfo; -#[cfg(not(target_feature = "shader"))] -use spirv_std::CrossWorkgroup; -#[cfg(target_feature = "shader")] -use spirv_std::{f32x4, Input, Output}; - -#[cfg(target_feature = "shader")] -#[allow(unused_attributes)] -#[spirv(entry = "fragment")] -pub fn main(input: Input, mut output: Output) { - output.store(input.load()) -} - -#[cfg(not(target_feature = "shader"))] -#[allow(unused_attributes)] -#[spirv(entry = "kernel")] -pub fn add_two_ints(x: CrossWorkgroup, y: CrossWorkgroup, mut z: CrossWorkgroup) { - z.store(x.load() + y.load()) -} - -#[panic_handler] -fn panic(_: &PanicInfo) -> ! { - loop {} -} diff --git a/rustc_codegen_spirv/run_libcore_test/.gitignore b/rustc_codegen_spirv/run_libcore_test/.gitignore deleted file mode 100644 index e9e21997b1..0000000000 --- a/rustc_codegen_spirv/run_libcore_test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -/Cargo.lock diff --git a/rustc_codegen_spirv/run_libcore_test/Cargo.toml b/rustc_codegen_spirv/run_libcore_test/Cargo.toml deleted file mode 100644 index 19826f3bc4..0000000000 --- a/rustc_codegen_spirv/run_libcore_test/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "run_libcore_test" -version = "0.1.0" -authors = ["Ashley Hauck "] -edition = "2018" - -[dependencies] -ocl = { version = "", features = ["opencl_version_2_1"] } - -[workspace] diff --git a/rustc_codegen_spirv/run_libcore_test/src/main.rs b/rustc_codegen_spirv/run_libcore_test/src/main.rs deleted file mode 100644 index bfac3549dd..0000000000 --- a/rustc_codegen_spirv/run_libcore_test/src/main.rs +++ /dev/null @@ -1,80 +0,0 @@ -use ocl::enums::ProgramInfo; -use ocl::{Buffer, Context, Kernel, Platform, Program, Queue}; -use std::ffi::CString; -use std::fs::File; -use std::io::Read; - -fn main() { - let path = "../build_libcore_test/target/spirv-unknown-unknown/release/build_libcore_test.spv"; - let mut spirv = Vec::new(); - File::open(path).unwrap().read_to_end(&mut spirv).unwrap(); - - let platform = Platform::list() - .into_iter() - .find(|p| p.version().unwrap().contains("2.")) - .unwrap(); - let context = Context::builder().platform(platform).build().unwrap(); - let device = context.devices()[0]; - println!( - "Using {} -> {}", - platform.name().unwrap(), - device.name().unwrap() - ); - let queue = Queue::new(&context, device, None).unwrap(); - let program = Program::with_il( - &spirv, - Some(&[device]), - &CString::new("").unwrap(), - &context, - ) - .unwrap(); - println!( - "Kernel names: {:?}", - program.info(ProgramInfo::KernelNames).unwrap() - ); - let one = Buffer::::builder() - .queue(queue.clone()) - .len(1) - .build() - .unwrap(); - let two = Buffer::::builder() - .queue(queue.clone()) - .len(1) - .build() - .unwrap(); - let three = Buffer::::builder() - .queue(queue.clone()) - .len(1) - .build() - .unwrap(); - - one.write(&[1u32] as &[u32]).enq().unwrap(); - two.write(&[2u32] as &[u32]).enq().unwrap(); - three.write(&[5u32] as &[u32]).enq().unwrap(); - - let kernel = Kernel::builder() - .queue(queue.clone()) - .program(&program) - .name("add_two_ints.1") - .local_work_size(&[1]) - .global_work_size(&[1]) - .arg(&one) - .arg(&two) - .arg(&three) - .build() - .unwrap(); - - unsafe { - kernel.enq().unwrap(); - } - - fn read(buf: Buffer) { - let mut vec = vec![0; 1]; - buf.read(&mut vec).enq().unwrap(); - println!("{:?}", vec); - } - - read(one); - read(two); - read(three); -} diff --git a/rustc_codegen_spirv/src/builder/mod.rs b/rustc_codegen_spirv/src/builder/mod.rs index 5b7717e221..853a794a49 100644 --- a/rustc_codegen_spirv/src/builder/mod.rs +++ b/rustc_codegen_spirv/src/builder/mod.rs @@ -273,7 +273,6 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> { let cast_dst = self.pointercast(dst.llval, cast_ptr_ty); self.store(val, cast_dst, arg_abi.layout.align.abi); } else { - // TODO: Does this need a from_immediate? The LLVM backend doesn't have one here. OperandValue::Immediate(val).store(self, dst); } } @@ -284,9 +283,7 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> { } impl<'a, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'tcx> { - fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) { - // TODO: Implement this? - } + fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) {} fn get_param(&self, index: usize) -> Self::Value { self.function_parameter_values.borrow()[&self.current_fn.def][index] diff --git a/rustc_codegen_spirv/tests/compile_and_val.rs b/rustc_codegen_spirv/tests/compile_and_val.rs deleted file mode 100644 index de51a2d621..0000000000 --- a/rustc_codegen_spirv/tests/compile_and_val.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::path::Path; -use std::process::Command; - -#[test] -pub fn build_libcore_test() { - { - // Unfortunately, as of right now, cargo does not rebuild projects if the .so provided by - // codegen-backend has changed. So, force a full rebuild always by deleting the target dir. - let target_dir = Path::new("build_libcore_test/target"); - if target_dir.exists() { - std::fs::remove_dir_all(target_dir).unwrap(); - } - } - let rustflags = format!( - "-Z codegen-backend={}rustc_codegen_spirv{}", - std::env::consts::DLL_PREFIX, - std::env::consts::DLL_SUFFIX - ); - let build = Command::new("cargo") - .args(&[ - "build", - "-Z", - "build-std=core", - "--target", - "spirv-unknown-unknown", - "--release", - ]) - .current_dir(Path::new("build_libcore_test").canonicalize().unwrap()) - .env("RUSTFLAGS", rustflags) - .env("SPIRV_VAL", "1") - .status() - .expect("failed to execute cargo build"); - if !build.success() { - panic!("build_libcore_test compilation failed with code {}", build); - } -} diff --git a/rustc_codegen_spirv/setup.bat b/setup.bat similarity index 100% rename from rustc_codegen_spirv/setup.bat rename to setup.bat diff --git a/rustc_codegen_spirv/setup.sh b/setup.sh similarity index 100% rename from rustc_codegen_spirv/setup.sh rename to setup.sh diff --git a/spirv-builder/Cargo.toml b/spirv-builder/Cargo.toml new file mode 100644 index 0000000000..f63d2eab16 --- /dev/null +++ b/spirv-builder/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "spirv-builder" +version = "0.1.0" +authors = ["khyperia "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "", features = ["derive"] } +serde_json = "" diff --git a/spirv-builder/src/lib.rs b/spirv-builder/src/lib.rs new file mode 100644 index 0000000000..7b85b04e9e --- /dev/null +++ b/spirv-builder/src/lib.rs @@ -0,0 +1,103 @@ +use serde::Deserialize; +use std::error::Error; +use std::fmt; +use std::path::Path; +use std::process::{Command, Output}; + +#[derive(Debug)] +pub enum SpirvBuilderError { + BuildFailed(Output), +} + +impl fmt::Display for SpirvBuilderError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SpirvBuilderError::BuildFailed(output) => write!( + f, + "{}\nstdout:\n{}\nstderr:\n{}", + output.status, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ), + } + } +} + +impl Error for SpirvBuilderError {} + +pub fn build_spirv( + path_to_rustc_codegen_spirv: impl AsRef, + path_to_crate: impl AsRef, +) -> Result<(), SpirvBuilderError> { + let path_to_built_codegen = build_rustc_codegen_spirv(path_to_rustc_codegen_spirv.as_ref())?; + let spirv_module = invoke_rustc(path_to_built_codegen, path_to_crate.as_ref())?; + let spirv_path: &Path = spirv_module.as_ref(); + let env_var = spirv_path.file_name().unwrap().to_str().unwrap(); + println!("cargo:rustc-env={}={}", env_var, spirv_module); + Ok(()) +} + +#[derive(Deserialize)] +struct RustcOutput { + reason: String, + filenames: Option>, +} +fn get_last_artifact(out: &str) -> String { + let out = serde_json::Deserializer::from_str(out).into_iter::(); + let last = out + .map(|line| line.unwrap()) + .filter(|line| line.reason == "compiler-artifact") + .last() + .expect("Did not find output file in rustc output"); + let mut filenames = last.filenames.unwrap(); + println!("{:?}", filenames); + assert_eq!(filenames.len(), 1); + filenames.pop().unwrap() +} + +fn build_rustc_codegen_spirv(path_to_codegen: &Path) -> Result { + let build = Command::new("cargo") + .args(&[ + "build", + "--message-format=json-render-diagnostics", + "--release", + ]) + .current_dir(path_to_codegen.canonicalize().unwrap()) + .output() + .expect("failed to execute cargo build"); + if build.status.success() { + Ok(get_last_artifact(&String::from_utf8(build.stdout).unwrap())) + } else { + Err(SpirvBuilderError::BuildFailed(build)) + } +} + +fn invoke_rustc( + path_to_built_codegen: String, + path_to_crate: &Path, +) -> Result { + let rustflags = format!( + "-Z codegen-backend={} -C target-feature=+shader", + path_to_built_codegen + ); + let build = Command::new("cargo") + .args(&[ + "build", + "--message-format=json-render-diagnostics", + "-Z", + "build-std=core", + "--target", + "spirv-unknown-unknown", + "--release", + ]) + .current_dir(path_to_crate.canonicalize().unwrap()) + .env("RUSTFLAGS", rustflags) + .env("SPIRV_VAL", "1") + .output() + .expect("failed to execute cargo build"); + if build.status.success() { + Ok(get_last_artifact(&String::from_utf8(build.stdout).unwrap())) + } else { + Err(SpirvBuilderError::BuildFailed(build)) + } +}