From 6ce9cbd67924c1d0b754a019eefe4f0a029101dd Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 10 May 2019 11:58:45 -0400 Subject: [PATCH 1/3] Remove Rust wrapper and examples --- Cargo.lock | 266 ------- Cargo.toml | 3 - Makefile | 25 +- examples/Cargo.toml | 30 - examples/hello_compute_rust/main.rs | 94 --- examples/hello_triangle_c/main.c | 1 + examples/hello_triangle_rust/main.rs | 128 ---- gfx-examples/Cargo.toml | 32 - gfx-examples/README.md | 6 - gfx-examples/data/cube.frag | 12 - gfx-examples/data/cube.vert | 16 - gfx-examples/data/shadow-bake.frag | 4 - gfx-examples/data/shadow-bake.vert | 18 - gfx-examples/data/shadow-forward.frag | 54 -- gfx-examples/data/shadow-forward.vert | 24 - gfx-examples/src/cube.rs | 345 --------- gfx-examples/src/framework.rs | 132 ---- gfx-examples/src/shadow.rs | 795 -------------------- wgpu-native/cbindgen.toml | 3 + wgpu-rs/Cargo.toml | 27 - wgpu-rs/src/lib.rs | 965 ------------------------- wgpu-rs/tests/multithreaded_compute.rs | 100 --- 22 files changed, 10 insertions(+), 3070 deletions(-) delete mode 100644 examples/Cargo.toml delete mode 100644 examples/hello_compute_rust/main.rs delete mode 100644 examples/hello_triangle_rust/main.rs delete mode 100644 gfx-examples/Cargo.toml delete mode 100644 gfx-examples/README.md delete mode 100644 gfx-examples/data/cube.frag delete mode 100644 gfx-examples/data/cube.vert delete mode 100644 gfx-examples/data/shadow-bake.frag delete mode 100644 gfx-examples/data/shadow-bake.vert delete mode 100644 gfx-examples/data/shadow-forward.frag delete mode 100644 gfx-examples/data/shadow-forward.vert delete mode 100644 gfx-examples/src/cube.rs delete mode 100644 gfx-examples/src/framework.rs delete mode 100644 gfx-examples/src/shadow.rs delete mode 100644 wgpu-rs/Cargo.toml delete mode 100644 wgpu-rs/src/lib.rs delete mode 100644 wgpu-rs/tests/multithreaded_compute.rs diff --git a/Cargo.lock b/Cargo.lock index 72d5904040..2a04f2eed5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,13 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "aho-corasick" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "andrew" version = "0.2.1" @@ -34,11 +26,6 @@ dependencies = [ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "arrayvec" version = "0.4.10" @@ -57,16 +44,6 @@ dependencies = [ "shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "autocfg" version = "0.1.2" @@ -114,20 +91,6 @@ name = "block" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "block-buffer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "byte-tools" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byteorder" version = "1.3.1" @@ -143,16 +106,6 @@ name = "cfg-if" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "cgmath" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -161,14 +114,6 @@ dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cmake" -version = "0.1.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cocoa" version = "0.18.4" @@ -250,14 +195,6 @@ dependencies = [ "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "digest" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "dlib" version = "0.4.1" @@ -271,27 +208,6 @@ name = "downcast-rs" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "env_logger" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "examples" -version = "0.1.0" -dependencies = [ - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu 0.2.2", - "wgpu-native 0.2.6", -] - [[package]] name = "failure" version = "0.1.5" @@ -312,11 +228,6 @@ dependencies = [ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fnv" version = "1.0.6" @@ -367,14 +278,6 @@ name = "gcc" version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "generic-array" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "gfx-backend-dx11" version = "0.1.1" @@ -458,17 +361,6 @@ dependencies = [ "xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "gfx-examples" -version = "0.1.0" -dependencies = [ - "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu 0.2.2", -] - [[package]] name = "gfx-hal" version = "0.1.0" @@ -479,24 +371,6 @@ dependencies = [ "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "glsl-to-spirv" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cmake 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "humantime" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "iovec" version = "0.1.2" @@ -602,11 +476,6 @@ dependencies = [ "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "memchr" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "memmap" version = "0.7.0" @@ -694,11 +563,6 @@ name = "num-traits" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "objc" version = "0.2.6" @@ -835,11 +699,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.6.12" @@ -974,34 +833,6 @@ name = "redox_syscall" version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "remove_dir_all" version = "0.5.1" @@ -1083,17 +914,6 @@ dependencies = [ "syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "sha2" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "shared_library" version = "0.1.9" @@ -1192,53 +1012,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termcolor" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "typenum" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "utf8-ranges" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "uuid" version = "0.7.4" @@ -1321,14 +1099,6 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "wgpu" -version = "0.2.2" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wgpu-native 0.2.6", -] - [[package]] name = "wgpu-native" version = "0.2.6" @@ -1398,15 +1168,6 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "wincolor" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "winit" version = "0.18.1" @@ -1485,28 +1246,21 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" "checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" "checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" "checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum ash 0.24.4 (registry+https://github.com/rust-lang/crates.io-index)" = "11f080bc0414ee1b6b959442cb36478d56c6e6b9bb2b04079a5048d9acc91a30" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" "checksum backtrace 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f106c02a3604afcdc0df5d36cc47b44b55917dbaf3d808f71c163a0ddba64637" "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum bincode 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "959c8e54c1ad412ffeeb95f05a9cade02d2d40a7b3c2f852d3353148f4beff35" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" -"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" "checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" "checksum cc 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "a0c56216487bb80eec9c4516337b2588a4f2a2290d72a1416d930e4dcdb0c90d" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" -"checksum cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "283944cdecc44bf0b8dd010ec9af888d3b4f142844fdbe026c20ef68148d6fe7" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "d9fc5523427cb1451da064f7db483d18bf8957e471baabf140ff683c37a86536" "checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b" "checksum copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59de7722d3b5c7b35dd519d617fe5116c9b879a0f145dc5431d78ab1f61d7c23" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" @@ -1516,13 +1270,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" "checksum d3d12 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4fda5547c55c93b070d59108464bbfd7d9da9563b2ce78fceefc6430e972a420" "checksum derivative 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6073e9676dbebdddeabaeb63e3b7cefd23c86f5c41d381ee1237cc77b1079898" -"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" "checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f" -"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -1531,15 +1282,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" -"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum gfx-backend-dx11 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe0bc43f1be34bfa182ed3575812848d72fb6e32315406adb98eeb0713f2a11a" "checksum gfx-backend-dx12 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "15d8bb2edd39dba0e87c2058d665364d45efd08cdf8bfa895be792491a95fcb4" "checksum gfx-backend-empty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "590c15369f88b88e4ea748da52b27a521a758a947b4aee995539c9f0cc1beb4c" "checksum gfx-backend-metal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66a0fa897619ea7f05e8841fe6214cf1b4e3f52d6a88ed51c2fbc6635a2d5517" "checksum gfx-backend-vulkan 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "982c618fd9ddeea7e68b2d872b9b6cf13024fc7d4033ba90f0e54ac0d33c798f" "checksum gfx-hal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84c470bce77fcaaea6854858682a99026ff796b880b0ca30511593a6b2bc77c0" -"checksum glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipc-channel 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79d98ee7dd1d2e796d254807fd86ea7189d07571aeaa74007603e29a79d15217" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -1553,7 +1301,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum metal 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd3f21d259068945192293b7a98b1c6844af9eb7602e393c405198b229efc157" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" @@ -1562,7 +1309,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "31d20fd2b37e07cf5125be68357b588672e8cefe9a96f8c17a9d46053b3e590d" "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" "checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc" @@ -1578,7 +1324,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" "checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" @@ -1594,9 +1339,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum range-alloc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5927936723a9e8b715d37d7e4b390455087c4bdf25b9f702309460577b14f9" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" @@ -1608,7 +1350,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd" "checksum serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "101b495b109a3e3ca8c4cbe44cf62391527cdfb6ba15821c5ce80bcd5ea23f9f" -"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" @@ -1620,13 +1361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.15.33 (registry+https://github.com/rust-lang/crates.io-index)" = "ec52cd796e5f01d0067225a5392e70084acc4c0013fa71d55166d38a8b307836" "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" @@ -1642,7 +1377,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum winit 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c57c15bd4c0ef18dff33e263e452abe32d00e2e05771cacaa410a14cc1c0776" "checksum wio 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Cargo.toml b/Cargo.toml index e3a0ffa1bc..f8760017e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,4 @@ members = [ "wgpu-native", "wgpu-remote", - "wgpu-rs", - "examples", - "gfx-examples", ] diff --git a/Makefile b/Makefile index ebefe95b55..0c1246ba38 100644 --- a/Makefile +++ b/Makefile @@ -30,9 +30,9 @@ else endif -.PHONY: all check test doc clear lib-native lib-remote lib-rust examples-rust examples-gfx gfx ffi-examples +.PHONY: all check test doc clear lib-native lib-remote examples-native examples-remote -all: examples-rust examples-gfx ffi-examples +all: examples-native examples-remote check: cargo check --all @@ -45,7 +45,7 @@ doc: clear: cargo clean - rm wgpu-bindings/wgpu.h + rm wgpu-bindings/wgpu.h wgpu-bindings/wgpu-remote.h lib-native: Cargo.lock wgpu-native/Cargo.toml $(wildcard wgpu-native/**/*.rs) cargo build --manifest-path wgpu-native/Cargo.toml --features "local,$(FEATURE_NATIVE)" @@ -53,27 +53,14 @@ lib-native: Cargo.lock wgpu-native/Cargo.toml $(wildcard wgpu-native/**/*.rs) lib-remote: Cargo.lock wgpu-remote/Cargo.toml $(wildcard wgpu-native/**/*.rs wgpu-remote/**/*.rs) cargo build --manifest-path wgpu-remote/Cargo.toml --features $(FEATURE_RUST) -lib-rust: Cargo.lock wgpu-rs/Cargo.toml $(wildcard wgpu-rs/**/*.rs) - cargo build --manifest-path wgpu-rs/Cargo.toml --features $(FEATURE_RUST) - ffi/wgpu.h: wgpu-native/cbindgen.toml $(wildcard wgpu-native/**/*.rs) cbindgen wgpu-native >ffi/wgpu.h ffi/wgpu-remote.h: wgpu-remote/cbindgen.toml $(wildcard wgpu-native/**/*.rs wgpu-remote/**/*.rs) cbindgen wgpu-remote >ffi/wgpu-remote.h -wgpu-bindings/*.h: Cargo.lock $(wildcard wgpu-bindings/src/*.rs) lib-native lib-remote - cargo +nightly run --manifest-path wgpu-bindings/Cargo.toml - -ffi-examples: lib-native lib-remote ffi/wgpu.h ffi/wgpu-remote.h +examples-native: lib-native ffi/wgpu.h examples/hello_triangle_c/main.c cd examples/hello_triangle_c && mkdir -p build && cd build && cmake .. && make + +examples-remote: lib-remote ffi/wgpu-remote.h examples/hello_remote_c/main.c cd examples/hello_remote_c && mkdir -p build && cd build && cmake .. && make - -examples-rust: examples/Cargo.toml $(wildcard wgpu-native/**/*.rs wgpu-rs/**/*.rs) - cargo build --manifest-path examples/Cargo.toml --features $(FEATURE_RUST) - -examples-gfx: examples-rust gfx-examples/Cargo.toml $(wildcard gfx-examples/*.rs) - cargo build --manifest-path gfx-examples/Cargo.toml --features $(FEATURE_RUST) - -gfx: - cargo run --manifest-path gfx-examples/Cargo.toml --bin $(name) --features $(FEATURE_RUST) diff --git a/examples/Cargo.toml b/examples/Cargo.toml deleted file mode 100644 index d440f8ff0f..0000000000 --- a/examples/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "examples" -version = "0.1.0" -authors = [ - "Dzmitry Malyshau ", - "Joshua Groves ", -] -edition = "2018" -publish = false - -[[bin]] -name = "hello_triangle" -path = "hello_triangle_rust/main.rs" - -[[bin]] -name = "hello_compute" -path = "hello_compute_rust/main.rs" - -[features] -default = [] -local = ["wgpu-native/local"] -metal = ["wgpu/metal"] -dx11 = ["wgpu/dx11"] -dx12 = ["wgpu/dx12"] -vulkan = ["wgpu/vulkan"] - -[dependencies] -wgpu-native = { path = "../wgpu-native" } -wgpu = { path = "../wgpu-rs" } -env_logger = "0.6" diff --git a/examples/hello_compute_rust/main.rs b/examples/hello_compute_rust/main.rs deleted file mode 100644 index 992e7dad3a..0000000000 --- a/examples/hello_compute_rust/main.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::str::FromStr; - -fn main() { - env_logger::init(); - - // For now this just panics if you didn't pass numbers. Could add proper error handling. - if std::env::args().len() == 1 { - panic!("You must pass a list of positive integers!") - } - let numbers: Vec = std::env::args() - .skip(1) - .map(|s| u32::from_str(&s).expect("You must pass a list of positive integers!")) - .collect(); - - let size = (numbers.len() * std::mem::size_of::()) as u32; - - let instance = wgpu::Instance::new(); - let adapter = instance.get_adapter(&wgpu::AdapterDescriptor { - power_preference: wgpu::PowerPreference::Default, - }); - let mut device = adapter.create_device(&wgpu::DeviceDescriptor { - extensions: wgpu::Extensions { - anisotropic_filtering: false, - }, - }); - - let cs_bytes = include_bytes!("./../data/collatz.comp.spv"); - let cs_module = device.create_shader_module(cs_bytes); - - let staging_buffer = device - .create_buffer_mapped( - numbers.len(), - wgpu::BufferUsageFlags::MAP_READ - | wgpu::BufferUsageFlags::TRANSFER_DST - | wgpu::BufferUsageFlags::TRANSFER_SRC, - ) - .fill_from_slice(&numbers); - - let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor { - size, - usage: wgpu::BufferUsageFlags::STORAGE - | wgpu::BufferUsageFlags::TRANSFER_DST - | wgpu::BufferUsageFlags::TRANSFER_SRC, - }); - - let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutBinding { - binding: 0, - visibility: wgpu::ShaderStageFlags::COMPUTE, - ty: wgpu::BindingType::StorageBuffer, - }], - }); - - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &storage_buffer, - range: 0..size, - }, - }], - }); - - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout], - }); - - let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - layout: &pipeline_layout, - compute_stage: wgpu::PipelineStageDescriptor { - module: &cs_module, - entry_point: "main", - }, - }); - - let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - encoder.copy_buffer_to_buffer(&staging_buffer, 0, &storage_buffer, 0, size); - { - let mut cpass = encoder.begin_compute_pass(); - cpass.set_pipeline(&compute_pipeline); - cpass.set_bind_group(0, &bind_group, &[]); - cpass.dispatch(numbers.len() as u32, 1, 1); - } - encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); - - device.get_queue().submit(&[encoder.finish()]); - - staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| { - if let Ok(mapping) = result { - println!("Times: {:?}", mapping.data); - } - }); -} diff --git a/examples/hello_triangle_c/main.c b/examples/hello_triangle_c/main.c index a83883d232..410c083903 100644 --- a/examples/hello_triangle_c/main.c +++ b/examples/hello_triangle_c/main.c @@ -1,5 +1,6 @@ #include "./../../ffi/wgpu.h" #include +#include #define WGPU_TARGET_MACOS 1 #define WGPU_TARGET_LINUX 2 diff --git a/examples/hello_triangle_rust/main.rs b/examples/hello_triangle_rust/main.rs deleted file mode 100644 index 30fd724ad7..0000000000 --- a/examples/hello_triangle_rust/main.rs +++ /dev/null @@ -1,128 +0,0 @@ -fn main() { - env_logger::init(); - - let instance = wgpu::Instance::new(); - let adapter = instance.get_adapter(&wgpu::AdapterDescriptor { - power_preference: wgpu::PowerPreference::LowPower, - }); - let mut device = adapter.create_device(&wgpu::DeviceDescriptor { - extensions: wgpu::Extensions { - anisotropic_filtering: false, - }, - }); - - let vs_bytes = include_bytes!("./../data/hello_triangle.vert.spv"); - let vs_module = device.create_shader_module(vs_bytes); - let fs_bytes = include_bytes!("./../data/hello_triangle.frag.spv"); - let fs_module = device.create_shader_module(fs_bytes); - - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: &[] }); - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[], - }); - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout], - }); - - let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - layout: &pipeline_layout, - vertex_stage: wgpu::PipelineStageDescriptor { - module: &vs_module, - entry_point: "main", - }, - fragment_stage: wgpu::PipelineStageDescriptor { - module: &fs_module, - entry_point: "main", - }, - rasterization_state: wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Ccw, - cull_mode: wgpu::CullMode::None, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }, - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[wgpu::ColorStateDescriptor { - format: wgpu::TextureFormat::Bgra8Unorm, - color: wgpu::BlendDescriptor::REPLACE, - alpha: wgpu::BlendDescriptor::REPLACE, - write_mask: wgpu::ColorWriteFlags::ALL, - }], - depth_stencil_state: None, - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[], - sample_count: 1, - }); - - use wgpu::winit::{ - ElementState, - Event, - EventsLoop, - KeyboardInput, - VirtualKeyCode, - Window, - WindowEvent, - }; - - let mut events_loop = EventsLoop::new(); - let window = Window::new(&events_loop).unwrap(); - let size = window - .get_inner_size() - .unwrap() - .to_physical(window.get_hidpi_factor()); - - let surface = instance.create_surface(&window); - let mut swap_chain = device.create_swap_chain( - &surface, - &wgpu::SwapChainDescriptor { - usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT, - format: wgpu::TextureFormat::Bgra8Unorm, - width: size.width.round() as u32, - height: size.height.round() as u32, - }, - ); - let mut running = true; - while running { - events_loop.poll_events(|event| match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::KeyboardInput { - input: - KeyboardInput { - virtual_keycode: Some(code), - state: ElementState::Pressed, - .. - }, - .. - } => match code { - VirtualKeyCode::Escape => running = false, - _ => {} - }, - WindowEvent::CloseRequested => running = false, - _ => {} - }, - _ => {} - }); - - let frame = swap_chain.get_next_texture(); - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color::GREEN, - }], - depth_stencil_attachment: None, - }); - rpass.set_pipeline(&render_pipeline); - rpass.set_bind_group(0, &bind_group, &[]); - rpass.draw(0..3, 0..1); - } - - device.get_queue().submit(&[encoder.finish()]); - } -} diff --git a/gfx-examples/Cargo.toml b/gfx-examples/Cargo.toml deleted file mode 100644 index 00fe76f62f..0000000000 --- a/gfx-examples/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "gfx-examples" -version = "0.1.0" -authors = [ - "Dzmitry Malyshau ", - "Joshua Groves ", -] -edition = "2018" -publish = false - -[[bin]] -name = "cube" -path = "src/cube.rs" - -[[bin]] -name = "shadow" -path = "src/shadow.rs" - -[features] -default = [] -metal-auto-capture = ["wgpu/metal-auto-capture"] -metal = ["wgpu/metal"] -dx11 = ["wgpu/dx11"] -dx12 = ["wgpu/dx12"] -vulkan = ["wgpu/vulkan"] - -[dependencies] -wgpu = { path = "../wgpu-rs" } -cgmath = "0.17" -env_logger = "0.6" -glsl-to-spirv = "0.1" -log = "0.4" diff --git a/gfx-examples/README.md b/gfx-examples/README.md deleted file mode 100644 index 1a56ea69f7..0000000000 --- a/gfx-examples/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# gfx pre-ll examples - -The original gfx-rs examples had grown over several years, but then were abandoned when the gfx API was changed to match Vulkan: -https://github.com/gfx-rs/gfx/tree/pre-ll/examples - -wgpu-rs is considered to be the spiritual successor of gfx pre-ll, so this is the new home for the examples. diff --git a/gfx-examples/data/cube.frag b/gfx-examples/data/cube.frag deleted file mode 100644 index b88e3abf0c..0000000000 --- a/gfx-examples/data/cube.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 450 - -layout(location = 0) in vec2 v_TexCoord; -layout(location = 0) out vec4 o_Target; -layout(set = 0, binding = 1) uniform texture2D t_Color; -layout(set = 0, binding = 2) uniform sampler s_Color; - -void main() { - vec4 tex = texture(sampler2D(t_Color, s_Color), v_TexCoord); - float mag = length(v_TexCoord-vec2(0.5)); - o_Target = mix(tex, vec4(0.0), mag*mag); -} diff --git a/gfx-examples/data/cube.vert b/gfx-examples/data/cube.vert deleted file mode 100644 index badc7fc203..0000000000 --- a/gfx-examples/data/cube.vert +++ /dev/null @@ -1,16 +0,0 @@ -#version 450 - -layout(location = 0) in vec4 a_Pos; -layout(location = 1) in vec2 a_TexCoord; -layout(location = 0) out vec2 v_TexCoord; - -layout(set = 0, binding = 0) uniform Locals { - mat4 u_Transform; -}; - -void main() { - v_TexCoord = a_TexCoord; - gl_Position = u_Transform * a_Pos; - // convert from -1,1 Z to 0,1 - gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w); -} diff --git a/gfx-examples/data/shadow-bake.frag b/gfx-examples/data/shadow-bake.frag deleted file mode 100644 index f0bcb49bf9..0000000000 --- a/gfx-examples/data/shadow-bake.frag +++ /dev/null @@ -1,4 +0,0 @@ -#version 450 - -void main() { -} diff --git a/gfx-examples/data/shadow-bake.vert b/gfx-examples/data/shadow-bake.vert deleted file mode 100644 index 32e257c6b7..0000000000 --- a/gfx-examples/data/shadow-bake.vert +++ /dev/null @@ -1,18 +0,0 @@ -#version 450 - -layout(location = 0) in ivec4 a_Pos; - -layout(set = 0, binding = 0) uniform Globals { - mat4 u_ViewProj; -}; - -layout(set = 1, binding = 0) uniform Entity { - mat4 u_World; - vec4 u_Color; -}; - -void main() { - gl_Position = u_ViewProj * u_World * vec4(a_Pos); - // convert from -1,1 Z to 0,1 - gl_Position.z = 0.5 * (gl_Position.z + gl_Position.w); -} diff --git a/gfx-examples/data/shadow-forward.frag b/gfx-examples/data/shadow-forward.frag deleted file mode 100644 index 9a2bd8fc67..0000000000 --- a/gfx-examples/data/shadow-forward.frag +++ /dev/null @@ -1,54 +0,0 @@ -#version 450 - -const int MAX_LIGHTS = 10; - -layout(location = 0) in vec3 v_Normal; -layout(location = 1) in vec4 v_Position; - -layout(location = 0) out vec4 o_Target; - -struct Light { - mat4 proj; - vec4 pos; - vec4 color; -}; - -layout(set = 0, binding = 0) uniform Globals { - mat4 u_ViewProj; - uvec4 u_NumLights; -}; -layout(set = 0, binding = 1) uniform Lights { - Light u_Lights[MAX_LIGHTS]; -}; -layout(set = 0, binding = 2) uniform texture2DArray t_Shadow; -layout(set = 0, binding = 3) uniform samplerShadow s_Shadow; - -layout(set = 1, binding = 0) uniform Entity { - mat4 u_World; - vec4 u_Color; -}; - - -void main() { - vec3 normal = normalize(v_Normal); - vec3 ambient = vec3(0.05, 0.05, 0.05); - // accumulate color - vec3 color = ambient; - for (int i=0; i Vertex { - Vertex { - _pos: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], - _tex_coord: [tc[0] as f32, tc[1] as f32], - } -} - -fn create_vertices() -> (Vec, Vec) { - let vertex_data = [ - // top (0, 0, 1) - vertex([-1, -1, 1], [0, 0]), - vertex([1, -1, 1], [1, 0]), - vertex([1, 1, 1], [1, 1]), - vertex([-1, 1, 1], [0, 1]), - // bottom (0, 0, -1) - vertex([-1, 1, -1], [1, 0]), - vertex([1, 1, -1], [0, 0]), - vertex([1, -1, -1], [0, 1]), - vertex([-1, -1, -1], [1, 1]), - // right (1, 0, 0) - vertex([1, -1, -1], [0, 0]), - vertex([1, 1, -1], [1, 0]), - vertex([1, 1, 1], [1, 1]), - vertex([1, -1, 1], [0, 1]), - // left (-1, 0, 0) - vertex([-1, -1, 1], [1, 0]), - vertex([-1, 1, 1], [0, 0]), - vertex([-1, 1, -1], [0, 1]), - vertex([-1, -1, -1], [1, 1]), - // front (0, 1, 0) - vertex([1, 1, -1], [1, 0]), - vertex([-1, 1, -1], [0, 0]), - vertex([-1, 1, 1], [0, 1]), - vertex([1, 1, 1], [1, 1]), - // back (0, -1, 0) - vertex([1, -1, 1], [0, 0]), - vertex([-1, -1, 1], [1, 0]), - vertex([-1, -1, -1], [1, 1]), - vertex([1, -1, -1], [0, 1]), - ]; - - let index_data: &[u16] = &[ - 0, 1, 2, 2, 3, 0, // top - 4, 5, 6, 6, 7, 4, // bottom - 8, 9, 10, 10, 11, 8, // right - 12, 13, 14, 14, 15, 12, // left - 16, 17, 18, 18, 19, 16, // front - 20, 21, 22, 22, 23, 20, // back - ]; - - (vertex_data.to_vec(), index_data.to_vec()) -} - -fn create_texels(size: usize) -> Vec { - use std::iter; - - (0..size * size) - .flat_map(|id| { - // get high five for recognizing this ;) - let cx = 3.0 * (id % size) as f32 / (size - 1) as f32 - 2.0; - let cy = 2.0 * (id / size) as f32 / (size - 1) as f32 - 1.0; - let (mut x, mut y, mut count) = (cx, cy, 0); - while count < 0xFF && x * x + y * y < 4.0 { - let old_x = x; - x = x * x - y * y + cx; - y = 2.0 * old_x * y + cy; - count += 1; - } - iter::once(0xFF - (count * 5) as u8) - .chain(iter::once(0xFF - (count * 15) as u8)) - .chain(iter::once(0xFF - (count * 50) as u8)) - .chain(iter::once(1)) - }) - .collect() -} - -struct Example { - vertex_buf: wgpu::Buffer, - index_buf: wgpu::Buffer, - index_count: usize, - bind_group: wgpu::BindGroup, - uniform_buf: wgpu::Buffer, - pipeline: wgpu::RenderPipeline, -} - -impl Example { - fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { - let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0); - let mx_view = cgmath::Matrix4::look_at( - cgmath::Point3::new(1.5f32, -5.0, 3.0), - cgmath::Point3::new(0f32, 0.0, 0.0), - -cgmath::Vector3::unit_z(), - ); - mx_projection * mx_view - } -} - -impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { - use std::mem; - - let mut init_encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - - // Create the vertex and index buffers - let vertex_size = mem::size_of::(); - let (vertex_data, index_data) = create_vertices(); - let vertex_buf = device - .create_buffer_mapped(vertex_data.len(), wgpu::BufferUsageFlags::VERTEX) - .fill_from_slice(&vertex_data); - - let index_buf = device - .create_buffer_mapped(index_data.len(), wgpu::BufferUsageFlags::INDEX) - .fill_from_slice(&index_data); - - // Create pipeline layout - let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[ - wgpu::BindGroupLayoutBinding { - binding: 0, - visibility: wgpu::ShaderStageFlags::VERTEX, - ty: wgpu::BindingType::UniformBuffer, - }, - wgpu::BindGroupLayoutBinding { - binding: 1, - visibility: wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::SampledTexture, - }, - wgpu::BindGroupLayoutBinding { - binding: 2, - visibility: wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::Sampler, - }, - ], - }); - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout], - }); - - // Create the texture - let size = 256u32; - let texels = create_texels(size as usize); - let texture_extent = wgpu::Extent3d { - width: size, - height: size, - depth: 1, - }; - let texture = device.create_texture(&wgpu::TextureDescriptor { - size: texture_extent, - array_size: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, - usage: wgpu::TextureUsageFlags::SAMPLED | wgpu::TextureUsageFlags::TRANSFER_DST, - }); - let texture_view = texture.create_default_view(); - let temp_buf = device - .create_buffer_mapped(texels.len(), wgpu::BufferUsageFlags::TRANSFER_SRC) - .fill_from_slice(&texels); - init_encoder.copy_buffer_to_texture( - wgpu::BufferCopyView { - buffer: &temp_buf, - offset: 0, - row_pitch: 4 * size, - image_height: size, - }, - wgpu::TextureCopyView { - texture: &texture, - level: 0, - slice: 0, - origin: wgpu::Origin3d { - x: 0.0, - y: 0.0, - z: 0.0, - }, - }, - texture_extent, - ); - - // Create other resources - let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - r_address_mode: wgpu::AddressMode::ClampToEdge, - s_address_mode: wgpu::AddressMode::ClampToEdge, - t_address_mode: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Nearest, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Nearest, - lod_min_clamp: -100.0, - lod_max_clamp: 100.0, - max_anisotropy: 0, - compare_function: wgpu::CompareFunction::Always, - border_color: wgpu::BorderColor::TransparentBlack, - }); - let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); - let mx_ref: &[f32; 16] = mx_total.as_ref(); - let uniform_buf = device - .create_buffer_mapped( - 16, - wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, - ) - .fill_from_slice(mx_ref); - - // Create bind group - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[ - wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - range: 0..64, - }, - }, - wgpu::Binding { - binding: 1, - resource: wgpu::BindingResource::TextureView(&texture_view), - }, - wgpu::Binding { - binding: 2, - resource: wgpu::BindingResource::Sampler(&sampler), - }, - ], - }); - - // Create the render pipeline - let vs_bytes = framework::load_glsl("cube.vert", framework::ShaderStage::Vertex); - let fs_bytes = framework::load_glsl("cube.frag", framework::ShaderStage::Fragment); - let vs_module = device.create_shader_module(&vs_bytes); - let fs_module = device.create_shader_module(&fs_bytes); - - let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - layout: &pipeline_layout, - vertex_stage: wgpu::PipelineStageDescriptor { - module: &vs_module, - entry_point: "main", - }, - fragment_stage: wgpu::PipelineStageDescriptor { - module: &fs_module, - entry_point: "main", - }, - rasterization_state: wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Cw, - cull_mode: wgpu::CullMode::Back, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }, - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[wgpu::ColorStateDescriptor { - format: sc_desc.format, - color: wgpu::BlendDescriptor::REPLACE, - alpha: wgpu::BlendDescriptor::REPLACE, - write_mask: wgpu::ColorWriteFlags::ALL, - }], - depth_stencil_state: None, - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[wgpu::VertexBufferDescriptor { - stride: vertex_size as u32, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - attribute_index: 0, - format: wgpu::VertexFormat::Float4, - offset: 0, - }, - wgpu::VertexAttributeDescriptor { - attribute_index: 1, - format: wgpu::VertexFormat::Float2, - offset: 4 * 4, - }, - ], - }], - sample_count: 1, - }); - - // Done - let init_command_buf = init_encoder.finish(); - device.get_queue().submit(&[init_command_buf]); - Example { - vertex_buf, - index_buf, - index_count: index_data.len(), - bind_group, - uniform_buf, - pipeline, - } - } - - fn update(&mut self, _event: wgpu::winit::WindowEvent) { - //empty - } - - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { - let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); - let mx_ref: &[f32; 16] = mx_total.as_ref(); - - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsageFlags::TRANSFER_SRC) - .fill_from_slice(mx_ref); - - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.uniform_buf, 0, 64); - device.get_queue().submit(&[encoder.finish()]); - } - - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 0.1, - g: 0.2, - b: 0.3, - a: 1.0, - }, - }], - depth_stencil_attachment: None, - }); - rpass.set_pipeline(&self.pipeline); - rpass.set_bind_group(0, &self.bind_group, &[]); - rpass.set_index_buffer(&self.index_buf, 0); - rpass.set_vertex_buffers(&[(&self.vertex_buf, 0)]); - rpass.draw_indexed(0..self.index_count as u32, 0, 0..1); - } - - device.get_queue().submit(&[encoder.finish()]); - } -} - -fn main() { - framework::run::("cube"); -} diff --git a/gfx-examples/src/framework.rs b/gfx-examples/src/framework.rs deleted file mode 100644 index abb1d5dba0..0000000000 --- a/gfx-examples/src/framework.rs +++ /dev/null @@ -1,132 +0,0 @@ -use log::info; - -#[allow(dead_code)] -pub fn cast_slice(data: &[T]) -> &[u8] { - use std::mem::size_of; - use std::slice::from_raw_parts; - - unsafe { from_raw_parts(data.as_ptr() as *const u8, data.len() * size_of::()) } -} - -#[allow(dead_code)] -pub enum ShaderStage { - Vertex, - Fragment, - Compute, -} - -pub fn load_glsl(name: &str, stage: ShaderStage) -> Vec { - use std::fs::read_to_string; - use std::io::Read; - use std::path::PathBuf; - - let ty = match stage { - ShaderStage::Vertex => glsl_to_spirv::ShaderType::Vertex, - ShaderStage::Fragment => glsl_to_spirv::ShaderType::Fragment, - ShaderStage::Compute => glsl_to_spirv::ShaderType::Compute, - }; - let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join("data") - .join(name); - let code = match read_to_string(&path) { - Ok(code) => code, - Err(e) => panic!("Unable to read {:?}: {:?}", path, e), - }; - - let mut output = glsl_to_spirv::compile(&code, ty).unwrap(); - let mut spv = Vec::new(); - output.read_to_end(&mut spv).unwrap(); - spv -} - -pub trait Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self; - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device); - fn update(&mut self, event: wgpu::winit::WindowEvent); - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device); -} - -pub fn run(title: &str) { - use wgpu::winit::{ - ElementState, - Event, - EventsLoop, - KeyboardInput, - VirtualKeyCode, - Window, - WindowEvent, - }; - - info!("Initializing the device..."); - env_logger::init(); - let instance = wgpu::Instance::new(); - let adapter = instance.get_adapter(&wgpu::AdapterDescriptor { - power_preference: wgpu::PowerPreference::LowPower, - }); - let mut device = adapter.create_device(&wgpu::DeviceDescriptor { - extensions: wgpu::Extensions { - anisotropic_filtering: false, - }, - }); - - info!("Initializing the window..."); - let mut events_loop = EventsLoop::new(); - let window = Window::new(&events_loop).unwrap(); - window.set_title(title); - let size = window - .get_inner_size() - .unwrap() - .to_physical(window.get_hidpi_factor()); - - let surface = instance.create_surface(&window); - let mut sc_desc = wgpu::SwapChainDescriptor { - usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT, - format: wgpu::TextureFormat::Bgra8Unorm, - width: size.width.round() as u32, - height: size.height.round() as u32, - }; - let mut swap_chain = device.create_swap_chain(&surface, &sc_desc); - - info!("Initializing the example..."); - let mut example = E::init(&sc_desc, &mut device); - - info!("Entering render loop..."); - let mut running = true; - while running { - events_loop.poll_events(|event| match event { - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - let physical = size.to_physical(window.get_hidpi_factor()); - info!("Resizing to {:?}", physical); - sc_desc.width = physical.width.round() as u32; - sc_desc.height = physical.height.round() as u32; - swap_chain = device.create_swap_chain(&surface, &sc_desc); - example.resize(&sc_desc, &mut device); - } - Event::WindowEvent { event, .. } => match event { - WindowEvent::KeyboardInput { - input: - KeyboardInput { - virtual_keycode: Some(VirtualKeyCode::Escape), - state: ElementState::Pressed, - .. - }, - .. - } - | WindowEvent::CloseRequested => { - running = false; - } - _ => { - example.update(event); - } - }, - _ => (), - }); - - let frame = swap_chain.get_next_texture(); - example.render(&frame, &mut device); - running &= !cfg!(feature = "metal-auto-capture"); - } -} diff --git a/gfx-examples/src/shadow.rs b/gfx-examples/src/shadow.rs deleted file mode 100644 index 5da7be96c8..0000000000 --- a/gfx-examples/src/shadow.rs +++ /dev/null @@ -1,795 +0,0 @@ -use std::mem; -use std::ops::Range; -use std::rc::Rc; - -mod framework; - -#[derive(Clone, Copy)] -struct Vertex { - _pos: [i8; 4], - _normal: [i8; 4], -} - -fn vertex(pos: [i8; 3], nor: [i8; 3]) -> Vertex { - Vertex { - _pos: [pos[0], pos[1], pos[2], 1], - _normal: [nor[0], nor[1], nor[2], 0], - } -} - -fn create_cube() -> (Vec, Vec) { - let vertex_data = [ - // top (0, 0, 1) - vertex([-1, -1, 1], [0, 0, 1]), - vertex([1, -1, 1], [0, 0, 1]), - vertex([1, 1, 1], [0, 0, 1]), - vertex([-1, 1, 1], [0, 0, 1]), - // bottom (0, 0, -1) - vertex([-1, 1, -1], [0, 0, -1]), - vertex([1, 1, -1], [0, 0, -1]), - vertex([1, -1, -1], [0, 0, -1]), - vertex([-1, -1, -1], [0, 0, -1]), - // right (1, 0, 0) - vertex([1, -1, -1], [1, 0, 0]), - vertex([1, 1, -1], [1, 0, 0]), - vertex([1, 1, 1], [1, 0, 0]), - vertex([1, -1, 1], [1, 0, 0]), - // left (-1, 0, 0) - vertex([-1, -1, 1], [-1, 0, 0]), - vertex([-1, 1, 1], [-1, 0, 0]), - vertex([-1, 1, -1], [-1, 0, 0]), - vertex([-1, -1, -1], [-1, 0, 0]), - // front (0, 1, 0) - vertex([1, 1, -1], [0, 1, 0]), - vertex([-1, 1, -1], [0, 1, 0]), - vertex([-1, 1, 1], [0, 1, 0]), - vertex([1, 1, 1], [0, 1, 0]), - // back (0, -1, 0) - vertex([1, -1, 1], [0, -1, 0]), - vertex([-1, -1, 1], [0, -1, 0]), - vertex([-1, -1, -1], [0, -1, 0]), - vertex([1, -1, -1], [0, -1, 0]), - ]; - - let index_data: &[u16] = &[ - 0, 1, 2, 2, 3, 0, // top - 4, 5, 6, 6, 7, 4, // bottom - 8, 9, 10, 10, 11, 8, // right - 12, 13, 14, 14, 15, 12, // left - 16, 17, 18, 18, 19, 16, // front - 20, 21, 22, 22, 23, 20, // back - ]; - - (vertex_data.to_vec(), index_data.to_vec()) -} - -fn create_plane(size: i8) -> (Vec, Vec) { - let vertex_data = [ - vertex([size, -size, 0], [0, 0, 1]), - vertex([size, size, 0], [0, 0, 1]), - vertex([-size, -size, 0], [0, 0, 1]), - vertex([-size, size, 0], [0, 0, 1]), - ]; - - let index_data: &[u16] = &[0, 1, 2, 2, 1, 3]; - - (vertex_data.to_vec(), index_data.to_vec()) -} - -struct Entity { - mx_world: cgmath::Matrix4, - rotation_speed: f32, - color: wgpu::Color, - vertex_buf: Rc, - index_buf: Rc, - index_count: usize, - bind_group: wgpu::BindGroup, - uniform_buf: wgpu::Buffer, -} - -struct Light { - pos: cgmath::Point3, - color: wgpu::Color, - fov: f32, - depth: Range, - target_view: wgpu::TextureView, -} - -#[repr(C)] -#[derive(Clone, Copy)] -struct LightRaw { - proj: [[f32; 4]; 4], - pos: [f32; 4], - color: [f32; 4], -} - -impl Light { - fn to_raw(&self) -> LightRaw { - use cgmath::{Deg, EuclideanSpace, Matrix4, PerspectiveFov, Point3, Vector3}; - - let mx_view = Matrix4::look_at(self.pos, Point3::origin(), -Vector3::unit_z()); - let projection = PerspectiveFov { - fovy: Deg(self.fov).into(), - aspect: 1.0, - near: self.depth.start, - far: self.depth.end, - }; - let mx_view_proj = cgmath::Matrix4::from(projection.to_perspective()) * mx_view; - LightRaw { - proj: *mx_view_proj.as_ref(), - pos: [self.pos.x, self.pos.y, self.pos.z, 1.0], - color: [self.color.r, self.color.g, self.color.b, 1.0], - } - } -} - -#[repr(C)] -#[derive(Clone, Copy)] -struct ForwardUniforms { - proj: [[f32; 4]; 4], - num_lights: [u32; 4], -} - -#[repr(C)] -#[derive(Clone, Copy)] -struct EntityUniforms { - model: cgmath::Matrix4, - color: [f32; 4], -} - -#[repr(C)] -struct ShadowUniforms { - proj: [[f32; 4]; 4], -} - -struct Pass { - pipeline: wgpu::RenderPipeline, - bind_group: wgpu::BindGroup, - uniform_buf: wgpu::Buffer, -} - -struct Example { - entities: Vec, - lights: Vec, - lights_are_dirty: bool, - shadow_pass: Pass, - forward_pass: Pass, - forward_depth: wgpu::TextureView, - light_uniform_buf: wgpu::Buffer, -} - -impl Example { - const MAX_LIGHTS: usize = 10; - const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::D32Float; - const SHADOW_SIZE: wgpu::Extent3d = wgpu::Extent3d { - width: 512, - height: 512, - depth: 1, - }; - const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::D32Float; - - fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { - let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0); - let mx_view = cgmath::Matrix4::look_at( - cgmath::Point3::new(3.0f32, -10.0, 6.0), - cgmath::Point3::new(0f32, 0.0, 0.0), - -cgmath::Vector3::unit_z(), - ); - mx_projection * mx_view - } -} - -impl framework::Example for Example { - fn init(sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) -> Self { - // Create the vertex and index buffers - let vertex_size = mem::size_of::(); - let (cube_vertex_data, cube_index_data) = create_cube(); - let cube_vertex_buf = Rc::new( - device - .create_buffer_mapped(cube_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX) - .fill_from_slice(&cube_vertex_data), - ); - - let cube_index_buf = Rc::new( - device - .create_buffer_mapped(cube_index_data.len(), wgpu::BufferUsageFlags::INDEX) - .fill_from_slice(&cube_index_data), - ); - - let (plane_vertex_data, plane_index_data) = create_plane(7); - let plane_vertex_buf = device - .create_buffer_mapped(plane_vertex_data.len(), wgpu::BufferUsageFlags::VERTEX) - .fill_from_slice(&plane_vertex_data); - - let plane_index_buf = device - .create_buffer_mapped(plane_index_data.len(), wgpu::BufferUsageFlags::INDEX) - .fill_from_slice(&plane_index_data); - - let entity_uniform_size = mem::size_of::() as u32; - let plane_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: entity_uniform_size, - usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, - }); - - let local_bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutBinding { - binding: 0, - visibility: wgpu::ShaderStageFlags::VERTEX | wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer, - }], - }); - - let mut entities = vec![{ - use cgmath::SquareMatrix; - - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &local_bind_group_layout, - bindings: &[wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &plane_uniform_buf, - range: 0..entity_uniform_size, - }, - }], - }); - Entity { - mx_world: cgmath::Matrix4::identity(), - rotation_speed: 0.0, - color: wgpu::Color::WHITE, - vertex_buf: Rc::new(plane_vertex_buf), - index_buf: Rc::new(plane_index_buf), - index_count: plane_index_data.len(), - bind_group, - uniform_buf: plane_uniform_buf, - } - }]; - - struct CubeDesc { - offset: cgmath::Vector3, - angle: f32, - scale: f32, - rotation: f32, - } - let cube_descs = [ - CubeDesc { - offset: cgmath::vec3(-2.0, -2.0, 2.0), - angle: 10.0, - scale: 0.7, - rotation: 1.0, - }, - CubeDesc { - offset: cgmath::vec3(2.0, -2.0, 2.0), - angle: 50.0, - scale: 1.3, - rotation: 2.0, - }, - CubeDesc { - offset: cgmath::vec3(-2.0, 2.0, 2.0), - angle: 140.0, - scale: 1.1, - rotation: 3.0, - }, - CubeDesc { - offset: cgmath::vec3(2.0, 2.0, 2.0), - angle: 210.0, - scale: 0.9, - rotation: 4.0, - }, - ]; - - for cube in &cube_descs { - use cgmath::{Decomposed, Deg, InnerSpace, Quaternion, Rotation3}; - - let transform = Decomposed { - disp: cube.offset.clone(), - rot: Quaternion::from_axis_angle(cube.offset.normalize(), Deg(cube.angle)), - scale: cube.scale, - }; - let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: entity_uniform_size, - usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, - }); - entities.push(Entity { - mx_world: cgmath::Matrix4::from(transform), - rotation_speed: cube.rotation, - color: wgpu::Color::GREEN, - vertex_buf: Rc::clone(&cube_vertex_buf), - index_buf: Rc::clone(&cube_index_buf), - index_count: cube_index_data.len(), - bind_group: device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &local_bind_group_layout, - bindings: &[wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - range: 0..entity_uniform_size, - }, - }], - }), - uniform_buf, - }); - } - - // Create other resources - let shadow_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - r_address_mode: wgpu::AddressMode::ClampToEdge, - s_address_mode: wgpu::AddressMode::ClampToEdge, - t_address_mode: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Nearest, - lod_min_clamp: -100.0, - lod_max_clamp: 100.0, - max_anisotropy: 0, - compare_function: wgpu::CompareFunction::LessEqual, - border_color: wgpu::BorderColor::TransparentBlack, - }); - - let shadow_texture = device.create_texture(&wgpu::TextureDescriptor { - size: Self::SHADOW_SIZE, - array_size: Self::MAX_LIGHTS as u32, - dimension: wgpu::TextureDimension::D2, - format: Self::SHADOW_FORMAT, - usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT | wgpu::TextureUsageFlags::SAMPLED, - }); - let shadow_view = shadow_texture.create_default_view(); - - let mut shadow_target_views = (0..2) - .map(|i| { - Some(shadow_texture.create_view(&wgpu::TextureViewDescriptor { - format: Self::SHADOW_FORMAT, - dimension: wgpu::TextureViewDimension::D2, - aspect: wgpu::TextureAspectFlags::DEPTH, - base_mip_level: 0, - level_count: 1, - base_array_layer: i as u32, - array_count: 1, - })) - }) - .collect::>(); - let lights = vec![ - Light { - pos: cgmath::Point3::new(7.0, -5.0, 10.0), - color: wgpu::Color { - r: 0.5, - g: 1.0, - b: 0.5, - a: 1.0, - }, - fov: 60.0, - depth: 1.0..20.0, - target_view: shadow_target_views[0].take().unwrap(), - }, - Light { - pos: cgmath::Point3::new(-5.0, 7.0, 10.0), - color: wgpu::Color { - r: 1.0, - g: 0.5, - b: 0.5, - a: 1.0, - }, - fov: 45.0, - depth: 1.0..20.0, - target_view: shadow_target_views[1].take().unwrap(), - }, - ]; - let light_uniform_size = (Self::MAX_LIGHTS * mem::size_of::()) as u32; - let light_uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: light_uniform_size, - usage: wgpu::BufferUsageFlags::UNIFORM - | wgpu::BufferUsageFlags::TRANSFER_SRC - | wgpu::BufferUsageFlags::TRANSFER_DST, - }); - - let vb_desc = wgpu::VertexBufferDescriptor { - stride: vertex_size as u32, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &[ - wgpu::VertexAttributeDescriptor { - attribute_index: 0, - format: wgpu::VertexFormat::Char4, - offset: 0, - }, - wgpu::VertexAttributeDescriptor { - attribute_index: 1, - format: wgpu::VertexFormat::Char4, - offset: 4 * 1, - }, - ], - }; - - let shadow_pass = { - // Create pipeline layout - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutBinding { - binding: 0, // global - visibility: wgpu::ShaderStageFlags::VERTEX, - ty: wgpu::BindingType::UniformBuffer, - }], - }); - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout], - }); - - let uniform_size = mem::size_of::() as u32; - let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor { - size: uniform_size, - usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, - }); - - // Create bind group - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - range: 0..uniform_size, - }, - }], - }); - - // Create the render pipeline - let vs_bytes = framework::load_glsl("shadow-bake.vert", framework::ShaderStage::Vertex); - let fs_bytes = - framework::load_glsl("shadow-bake.frag", framework::ShaderStage::Fragment); - let vs_module = device.create_shader_module(&vs_bytes); - let fs_module = device.create_shader_module(&fs_bytes); - - let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - layout: &pipeline_layout, - vertex_stage: wgpu::PipelineStageDescriptor { - module: &vs_module, - entry_point: "main", - }, - fragment_stage: wgpu::PipelineStageDescriptor { - module: &fs_module, - entry_point: "main", - }, - rasterization_state: wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Cw, - cull_mode: wgpu::CullMode::Back, - depth_bias: 2, // corresponds to bilinear filtering - depth_bias_slope_scale: 2.0, - depth_bias_clamp: 0.0, - }, - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[], - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { - format: Self::SHADOW_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::LessEqual, - stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, - stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }), - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[vb_desc.clone()], - sample_count: 1, - }); - - Pass { - pipeline, - bind_group, - uniform_buf, - } - }; - - let forward_pass = { - // Create pipeline layout - let bind_group_layout = - device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[ - wgpu::BindGroupLayoutBinding { - binding: 0, // global - visibility: wgpu::ShaderStageFlags::VERTEX - | wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer, - }, - wgpu::BindGroupLayoutBinding { - binding: 1, // lights - visibility: wgpu::ShaderStageFlags::VERTEX - | wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::UniformBuffer, - }, - wgpu::BindGroupLayoutBinding { - binding: 2, - visibility: wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::SampledTexture, - }, - wgpu::BindGroupLayoutBinding { - binding: 3, - visibility: wgpu::ShaderStageFlags::FRAGMENT, - ty: wgpu::BindingType::Sampler, - }, - ], - }); - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout, &local_bind_group_layout], - }); - - let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); - let forward_uniforms = ForwardUniforms { - proj: *mx_total.as_ref(), - num_lights: [lights.len() as u32, 0, 0, 0], - }; - let uniform_size = mem::size_of::() as u32; - let uniform_buf = device - .create_buffer_mapped( - 1, - wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, - ) - .fill_from_slice(&[forward_uniforms]); - - // Create bind group - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[ - wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &uniform_buf, - range: 0..uniform_size, - }, - }, - wgpu::Binding { - binding: 1, - resource: wgpu::BindingResource::Buffer { - buffer: &light_uniform_buf, - range: 0..light_uniform_size, - }, - }, - wgpu::Binding { - binding: 2, - resource: wgpu::BindingResource::TextureView(&shadow_view), - }, - wgpu::Binding { - binding: 3, - resource: wgpu::BindingResource::Sampler(&shadow_sampler), - }, - ], - }); - - // Create the render pipeline - let vs_bytes = - framework::load_glsl("shadow-forward.vert", framework::ShaderStage::Vertex); - let fs_bytes = - framework::load_glsl("shadow-forward.frag", framework::ShaderStage::Fragment); - let vs_module = device.create_shader_module(&vs_bytes); - let fs_module = device.create_shader_module(&fs_bytes); - - let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - layout: &pipeline_layout, - vertex_stage: wgpu::PipelineStageDescriptor { - module: &vs_module, - entry_point: "main", - }, - fragment_stage: wgpu::PipelineStageDescriptor { - module: &fs_module, - entry_point: "main", - }, - rasterization_state: wgpu::RasterizationStateDescriptor { - front_face: wgpu::FrontFace::Cw, - cull_mode: wgpu::CullMode::Back, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - }, - primitive_topology: wgpu::PrimitiveTopology::TriangleList, - color_states: &[wgpu::ColorStateDescriptor { - format: sc_desc.format, - color: wgpu::BlendDescriptor::REPLACE, - alpha: wgpu::BlendDescriptor::REPLACE, - write_mask: wgpu::ColorWriteFlags::ALL, - }], - depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { - format: Self::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, - stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, - stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE, - stencil_read_mask: 0, - stencil_write_mask: 0, - }), - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[vb_desc], - sample_count: 1, - }); - - Pass { - pipeline, - bind_group, - uniform_buf, - } - }; - - let depth_texture = device.create_texture(&wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: sc_desc.width, - height: sc_desc.height, - depth: 1, - }, - array_size: 1, - dimension: wgpu::TextureDimension::D2, - format: Self::DEPTH_FORMAT, - usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT, - }); - - Example { - entities, - lights, - lights_are_dirty: true, - shadow_pass, - forward_pass, - forward_depth: depth_texture.create_default_view(), - light_uniform_buf, - } - } - - fn update(&mut self, _event: wgpu::winit::WindowEvent) { - //empty - } - - fn resize(&mut self, sc_desc: &wgpu::SwapChainDescriptor, device: &mut wgpu::Device) { - { - let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); - let mx_ref: &[f32; 16] = mx_total.as_ref(); - let temp_buf = device - .create_buffer_mapped(16, wgpu::BufferUsageFlags::TRANSFER_SRC) - .fill_from_slice(mx_ref); - - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - encoder.copy_buffer_to_buffer(&temp_buf, 0, &self.forward_pass.uniform_buf, 0, 64); - device.get_queue().submit(&[encoder.finish()]); - } - - let depth_texture = device.create_texture(&wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: sc_desc.width, - height: sc_desc.height, - depth: 1, - }, - array_size: 1, - dimension: wgpu::TextureDimension::D2, - format: Self::DEPTH_FORMAT, - usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT, - }); - self.forward_depth = depth_texture.create_default_view(); - } - - fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - - { - let size = mem::size_of::() as u32; - let temp_buf_data = device - .create_buffer_mapped(self.entities.len(), wgpu::BufferUsageFlags::TRANSFER_SRC); - - for (i, entity) in self.entities.iter_mut().enumerate() { - if entity.rotation_speed != 0.0 { - let rotation = - cgmath::Matrix4::from_angle_x(cgmath::Deg(entity.rotation_speed)); - entity.mx_world = entity.mx_world * rotation; - } - temp_buf_data.data[i] = EntityUniforms { - model: entity.mx_world.clone(), - color: [ - entity.color.r, - entity.color.g, - entity.color.b, - entity.color.a, - ], - }; - } - - let temp_buf = temp_buf_data.finish(); - - for (i, entity) in self.entities.iter().enumerate() { - encoder.copy_buffer_to_buffer( - &temp_buf, - i as u32 * size, - &entity.uniform_buf, - 0, - size, - ); - } - } - - if self.lights_are_dirty { - self.lights_are_dirty = false; - let size = (self.lights.len() * mem::size_of::()) as u32; - let temp_buf_data = device - .create_buffer_mapped(self.lights.len(), wgpu::BufferUsageFlags::TRANSFER_SRC); - for (i, light) in self.lights.iter().enumerate() { - temp_buf_data.data[i] = light.to_raw(); - } - encoder.copy_buffer_to_buffer( - &temp_buf_data.finish(), - 0, - &self.light_uniform_buf, - 0, - size, - ); - } - - for (i, light) in self.lights.iter().enumerate() { - // The light uniform buffer already has the projection, - // let's just copy it over to the shadow uniform buffer. - encoder.copy_buffer_to_buffer( - &self.light_uniform_buf, - (i * mem::size_of::()) as u32, - &self.shadow_pass.uniform_buf, - 0, - 64, - ); - - let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[], - depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { - attachment: &light.target_view, - depth_load_op: wgpu::LoadOp::Clear, - depth_store_op: wgpu::StoreOp::Store, - stencil_load_op: wgpu::LoadOp::Clear, - stencil_store_op: wgpu::StoreOp::Store, - clear_depth: 1.0, - clear_stencil: 0, - }), - }); - pass.set_pipeline(&self.shadow_pass.pipeline); - pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]); - - for entity in &self.entities { - pass.set_bind_group(1, &entity.bind_group, &[]); - pass.set_index_buffer(&entity.index_buf, 0); - pass.set_vertex_buffers(&[(&entity.vertex_buf, 0)]); - pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); - } - } - - // forward pass - { - let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { - attachment: &frame.view, - load_op: wgpu::LoadOp::Clear, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 0.1, - g: 0.2, - b: 0.3, - a: 1.0, - }, - }], - depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { - attachment: &self.forward_depth, - depth_load_op: wgpu::LoadOp::Clear, - depth_store_op: wgpu::StoreOp::Store, - stencil_load_op: wgpu::LoadOp::Clear, - stencil_store_op: wgpu::StoreOp::Store, - clear_depth: 1.0, - clear_stencil: 0, - }), - }); - pass.set_pipeline(&self.forward_pass.pipeline); - pass.set_bind_group(0, &self.forward_pass.bind_group, &[]); - - for entity in &self.entities { - pass.set_bind_group(1, &entity.bind_group, &[]); - pass.set_index_buffer(&entity.index_buf, 0); - pass.set_vertex_buffers(&[(&entity.vertex_buf, 0)]); - pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); - } - } - - device.get_queue().submit(&[encoder.finish()]); - } -} - -fn main() { - framework::run::("shadow"); -} diff --git a/wgpu-native/cbindgen.toml b/wgpu-native/cbindgen.toml index bb01f70453..5ac37d90ee 100644 --- a/wgpu-native/cbindgen.toml +++ b/wgpu-native/cbindgen.toml @@ -7,6 +7,8 @@ language = "C" [export] prefix = "WGPU" +#TODO: figure out why cbindgen even tries to export a private type... +exclude = ["BufferMapResult"] [parse] parse_deps = false @@ -28,4 +30,5 @@ bitflags = true [defines] "feature = window-winit" = "WGPU_WINDOW_WINIT" +"feature = local" = "WGPU_LOCAL" "feature = remote" = "WGPU_REMOTE" diff --git a/wgpu-rs/Cargo.toml b/wgpu-rs/Cargo.toml deleted file mode 100644 index c5046d8d56..0000000000 --- a/wgpu-rs/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "wgpu" -version = "0.2.2" -authors = [ - "Dzmitry Malyshau ", - "Joshua Groves ", -] -edition = "2018" -description = "WebGPU native Rust wrapper" -homepage = "https://github.com/gfx-rs/wgpu" -repository = "https://github.com/gfx-rs/wgpu" -keywords = ["graphics"] -license = "MPL-2.0" - -[lib] - -[features] -default = [] -metal-auto-capture = ["wgn/metal-auto-capture"] -metal = ["wgn/gfx-backend-metal"] -dx11 = ["wgn/gfx-backend-dx11"] -dx12 = ["wgn/gfx-backend-dx12"] -vulkan = ["wgn/gfx-backend-vulkan"] - -[dependencies] -wgn = { package = "wgpu-native", version = "0.2.5", path = "../wgpu-native", features = ["local", "window-winit"] } -arrayvec = "0.4" diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs deleted file mode 100644 index 61705e057e..0000000000 --- a/wgpu-rs/src/lib.rs +++ /dev/null @@ -1,965 +0,0 @@ -use arrayvec::ArrayVec; - -use std::ffi::CString; -use std::ops::Range; -use std::ptr; -use std::slice; - -pub use wgn::winit; -pub use wgn::{ - AdapterDescriptor, - AddressMode, - BindGroupLayoutBinding, - BindingType, - BlendDescriptor, - BlendFactor, - BlendOperation, - BorderColor, - BufferDescriptor, - BufferMapAsyncStatus, - BufferUsageFlags, - Color, - ColorStateDescriptor, - ColorWriteFlags, - CommandEncoderDescriptor, - CompareFunction, - CullMode, - DepthStencilStateDescriptor, - DeviceDescriptor, - Extensions, - Extent3d, - FilterMode, - FrontFace, - IndexFormat, - InputStepMode, - LoadOp, - Origin3d, - PowerPreference, - PrimitiveTopology, - RasterizationStateDescriptor, - RenderPassColorAttachmentDescriptor, - RenderPassDepthStencilAttachmentDescriptor, - SamplerDescriptor, - ShaderAttributeIndex, - ShaderModuleDescriptor, - ShaderStageFlags, - StencilOperation, - StencilStateFaceDescriptor, - StoreOp, - SwapChainDescriptor, - TextureAspectFlags, - TextureDescriptor, - TextureDimension, - TextureFormat, - TextureUsageFlags, - TextureViewDescriptor, - TextureViewDimension, - VertexAttributeDescriptor, - VertexFormat, -}; - -//TODO: avoid heap allocating vectors during resource creation. -#[derive(Default)] -struct Temp { - //bind_group_descriptors: Vec, - //vertex_buffers: Vec, - command_buffers: Vec, -} - -pub struct Instance { - id: wgn::InstanceId, -} - -pub struct Adapter { - id: wgn::AdapterId, -} - -pub struct Device { - id: wgn::DeviceId, - temp: Temp, -} - -pub struct Buffer { - id: wgn::BufferId, -} - -pub struct Texture { - id: wgn::TextureId, - owned: bool, -} - -pub struct TextureView { - id: wgn::TextureViewId, - owned: bool, -} - -pub struct Sampler { - id: wgn::SamplerId, -} - -pub struct Surface { - id: wgn::SurfaceId, -} - -pub struct SwapChain { - id: wgn::SwapChainId, -} - -pub struct BindGroupLayout { - id: wgn::BindGroupLayoutId, -} - -pub struct BindGroup { - id: wgn::BindGroupId, -} - -impl Drop for BindGroup { - fn drop(&mut self) { - wgn::wgpu_bind_group_destroy(self.id); - } -} - -pub struct ShaderModule { - id: wgn::ShaderModuleId, -} - -pub struct PipelineLayout { - id: wgn::PipelineLayoutId, -} - -pub struct RenderPipeline { - id: wgn::RenderPipelineId, -} - -pub struct ComputePipeline { - id: wgn::ComputePipelineId, -} - -pub struct CommandBuffer { - id: wgn::CommandBufferId, -} - -pub struct CommandEncoder { - id: wgn::CommandEncoderId, -} - -pub struct RenderPass<'a> { - id: wgn::RenderPassId, - _parent: &'a mut CommandEncoder, -} - -pub struct ComputePass<'a> { - id: wgn::ComputePassId, - _parent: &'a mut CommandEncoder, -} - -pub struct Queue<'a> { - id: wgn::QueueId, - temp: &'a mut Temp, -} - -pub enum BindingResource<'a> { - Buffer { - buffer: &'a Buffer, - range: Range, - }, - Sampler(&'a Sampler), - TextureView(&'a TextureView), -} - -pub struct Binding<'a> { - pub binding: u32, - pub resource: BindingResource<'a>, -} - -pub struct BindGroupLayoutDescriptor<'a> { - pub bindings: &'a [BindGroupLayoutBinding], -} - -pub struct BindGroupDescriptor<'a> { - pub layout: &'a BindGroupLayout, - pub bindings: &'a [Binding<'a>], -} - -pub struct PipelineLayoutDescriptor<'a> { - pub bind_group_layouts: &'a [&'a BindGroupLayout], -} - -pub struct PipelineStageDescriptor<'a> { - pub module: &'a ShaderModule, - pub entry_point: &'a str, -} - -#[derive(Clone, Debug)] -pub struct VertexBufferDescriptor<'a> { - pub stride: u32, - pub step_mode: InputStepMode, - pub attributes: &'a [VertexAttributeDescriptor], -} - -pub struct RenderPipelineDescriptor<'a> { - pub layout: &'a PipelineLayout, - pub vertex_stage: PipelineStageDescriptor<'a>, - pub fragment_stage: PipelineStageDescriptor<'a>, - pub rasterization_state: RasterizationStateDescriptor, - pub primitive_topology: PrimitiveTopology, - pub color_states: &'a [ColorStateDescriptor], - pub depth_stencil_state: Option, - pub index_format: IndexFormat, - pub vertex_buffers: &'a [VertexBufferDescriptor<'a>], - pub sample_count: u32, -} - -pub struct ComputePipelineDescriptor<'a> { - pub layout: &'a PipelineLayout, - pub compute_stage: PipelineStageDescriptor<'a>, -} - -pub struct RenderPassDescriptor<'a> { - pub color_attachments: &'a [RenderPassColorAttachmentDescriptor<&'a TextureView>], - pub depth_stencil_attachment: - Option>, -} - -pub struct SwapChainOutput<'a> { - pub texture: Texture, - pub view: TextureView, - swap_chain_id: &'a wgn::SwapChainId, -} - -pub struct BufferCopyView<'a> { - pub buffer: &'a Buffer, - pub offset: u32, - pub row_pitch: u32, - pub image_height: u32, -} - -impl<'a> BufferCopyView<'a> { - fn into_native(self) -> wgn::BufferCopyView { - wgn::BufferCopyView { - buffer: self.buffer.id, - offset: self.offset, - row_pitch: self.row_pitch, - image_height: self.image_height, - } - } -} - -pub struct TextureCopyView<'a> { - pub texture: &'a Texture, - pub level: u32, - pub slice: u32, - pub origin: Origin3d, -} - -impl<'a> TextureCopyView<'a> { - fn into_native(self) -> wgn::TextureCopyView { - wgn::TextureCopyView { - texture: self.texture.id, - level: self.level, - slice: self.slice, - origin: self.origin, - } - } -} - -pub struct CreateBufferMapped<'a, T> { - id: wgn::BufferId, - pub data: &'a mut [T], -} - -impl<'a, T> CreateBufferMapped<'a, T> -where - T: Copy, -{ - pub fn fill_from_slice(self, slice: &[T]) -> Buffer { - self.data.copy_from_slice(slice); - self.finish() - } - - pub fn finish(self) -> Buffer { - wgn::wgpu_buffer_unmap(self.id); - Buffer { id: self.id } - } -} - -impl Instance { - pub fn new() -> Self { - Instance { - id: wgn::wgpu_create_instance(), - } - } - - pub fn get_adapter(&self, desc: &AdapterDescriptor) -> Adapter { - Adapter { - id: wgn::wgpu_instance_get_adapter(self.id, desc), - } - } - - pub fn create_surface(&self, window: &winit::Window) -> Surface { - Surface { - id: wgn::wgpu_instance_create_surface_from_winit(self.id, window), - } - } - - #[cfg(feature = "metal")] - pub fn create_surface_with_metal_layer(&self, window: *mut std::ffi::c_void) -> Surface { - Surface { - id: wgn::wgpu_instance_create_surface_from_macos_layer(self.id, window), - } - } -} - -impl Adapter { - pub fn create_device(&self, desc: &DeviceDescriptor) -> Device { - Device { - id: wgn::wgpu_adapter_create_device(self.id, desc), - temp: Temp::default(), - } - } -} - -impl Device { - /// Check for resource cleanups and mapping callbacks. - pub fn poll(&self, force_wait: bool) { - wgn::wgpu_device_poll(self.id, force_wait); - } - - pub fn create_shader_module(&self, spv: &[u8]) -> ShaderModule { - let desc = wgn::ShaderModuleDescriptor { - code: wgn::ByteArray { - bytes: spv.as_ptr(), - length: spv.len(), - }, - }; - ShaderModule { - id: wgn::wgpu_device_create_shader_module(self.id, &desc), - } - } - - pub fn get_queue(&mut self) -> Queue { - Queue { - id: wgn::wgpu_device_get_queue(self.id), - temp: &mut self.temp, - } - } - - pub fn create_command_encoder(&self, desc: &CommandEncoderDescriptor) -> CommandEncoder { - CommandEncoder { - id: wgn::wgpu_device_create_command_encoder(self.id, desc), - } - } - - pub fn create_bind_group(&self, desc: &BindGroupDescriptor) -> BindGroup { - let bindings = desc - .bindings - .into_iter() - .map(|binding| wgn::Binding { - binding: binding.binding, - resource: match binding.resource { - BindingResource::Buffer { - ref buffer, - ref range, - } => wgn::BindingResource::Buffer(wgn::BufferBinding { - buffer: buffer.id, - offset: range.start, - size: range.end - range.start, - }), - BindingResource::Sampler(ref sampler) => { - wgn::BindingResource::Sampler(sampler.id) - } - BindingResource::TextureView(ref texture_view) => { - wgn::BindingResource::TextureView(texture_view.id) - } - }, - }) - .collect::>(); - BindGroup { - id: wgn::wgpu_device_create_bind_group( - self.id, - &wgn::BindGroupDescriptor { - layout: desc.layout.id, - bindings: bindings.as_ptr(), - bindings_length: bindings.len(), - }, - ), - } - } - - pub fn create_bind_group_layout(&self, desc: &BindGroupLayoutDescriptor) -> BindGroupLayout { - BindGroupLayout { - id: wgn::wgpu_device_create_bind_group_layout( - self.id, - &wgn::BindGroupLayoutDescriptor { - bindings: desc.bindings.as_ptr(), - bindings_length: desc.bindings.len(), - }, - ), - } - } - - pub fn create_pipeline_layout(&self, desc: &PipelineLayoutDescriptor) -> PipelineLayout { - //TODO: avoid allocation here - let temp_layouts = desc - .bind_group_layouts - .iter() - .map(|bgl| bgl.id) - .collect::>(); - PipelineLayout { - id: wgn::wgpu_device_create_pipeline_layout( - self.id, - &wgn::PipelineLayoutDescriptor { - bind_group_layouts: temp_layouts.as_ptr(), - bind_group_layouts_length: temp_layouts.len(), - }, - ), - } - } - - pub fn create_render_pipeline(&self, desc: &RenderPipelineDescriptor) -> RenderPipeline { - let vertex_entry_point = CString::new(desc.vertex_stage.entry_point).unwrap(); - let fragment_entry_point = CString::new(desc.fragment_stage.entry_point).unwrap(); - - let temp_color_states = desc.color_states.to_vec(); - let temp_vertex_buffers = desc - .vertex_buffers - .iter() - .map(|vbuf| wgn::VertexBufferDescriptor { - stride: vbuf.stride, - step_mode: vbuf.step_mode, - attributes: vbuf.attributes.as_ptr(), - attributes_count: vbuf.attributes.len(), - }) - .collect::>(); - - RenderPipeline { - id: wgn::wgpu_device_create_render_pipeline( - self.id, - &wgn::RenderPipelineDescriptor { - layout: desc.layout.id, - vertex_stage: wgn::PipelineStageDescriptor { - module: desc.vertex_stage.module.id, - entry_point: vertex_entry_point.as_ptr(), - }, - fragment_stage: wgn::PipelineStageDescriptor { - module: desc.fragment_stage.module.id, - entry_point: fragment_entry_point.as_ptr(), - }, - rasterization_state: desc.rasterization_state.clone(), - primitive_topology: desc.primitive_topology, - color_states: temp_color_states.as_ptr(), - color_states_length: temp_color_states.len(), - depth_stencil_state: desc - .depth_stencil_state - .as_ref() - .map_or(ptr::null(), |p| p as *const _), - vertex_buffer_state: wgn::VertexBufferStateDescriptor { - index_format: desc.index_format, - vertex_buffers: temp_vertex_buffers.as_ptr(), - vertex_buffers_count: temp_vertex_buffers.len(), - }, - sample_count: desc.sample_count, - }, - ), - } - } - - pub fn create_compute_pipeline(&self, desc: &ComputePipelineDescriptor) -> ComputePipeline { - let entry_point = CString::new(desc.compute_stage.entry_point).unwrap(); - - ComputePipeline { - id: wgn::wgpu_device_create_compute_pipeline( - self.id, - &wgn::ComputePipelineDescriptor { - layout: desc.layout.id, - compute_stage: wgn::PipelineStageDescriptor { - module: desc.compute_stage.module.id, - entry_point: entry_point.as_ptr(), - }, - }, - ), - } - } - - pub fn create_buffer(&self, desc: &BufferDescriptor) -> Buffer { - Buffer { - id: wgn::wgpu_device_create_buffer(self.id, desc), - } - } - - pub fn create_buffer_mapped<'a, T>( - &self, - count: usize, - usage: BufferUsageFlags, - ) -> CreateBufferMapped<'a, T> - where - T: 'static + Copy, - { - let type_size = std::mem::size_of::() as u32; - assert_ne!(type_size, 0); - - let desc = BufferDescriptor { - size: (type_size * count as u32).max(1), - usage, - }; - let mut ptr: *mut u8 = std::ptr::null_mut(); - - let id = wgn::wgpu_device_create_buffer_mapped(self.id, &desc, &mut ptr as *mut *mut u8); - - let data = unsafe { std::slice::from_raw_parts_mut(ptr as *mut T, count) }; - - CreateBufferMapped { id, data } - } - - pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture { - Texture { - id: wgn::wgpu_device_create_texture(self.id, desc), - owned: true, - } - } - - pub fn create_sampler(&self, desc: &SamplerDescriptor) -> Sampler { - Sampler { - id: wgn::wgpu_device_create_sampler(self.id, desc), - } - } - - pub fn create_swap_chain(&self, surface: &Surface, desc: &SwapChainDescriptor) -> SwapChain { - SwapChain { - id: wgn::wgpu_device_create_swap_chain(self.id, surface.id, desc), - } - } -} - -impl Drop for Device { - fn drop(&mut self) { - wgn::wgpu_device_poll(self.id, true); - //TODO: make this work in general - #[cfg(feature = "metal-auto-capture")] - wgn::wgpu_device_destroy(self.id); - } -} - -pub struct BufferAsyncMapping { - pub data: T, - buffer_id: wgn::BufferId, -} -//TODO: proper error type -pub type BufferMapAsyncResult = Result, ()>; - -impl Drop for BufferAsyncMapping { - fn drop(&mut self) { - wgn::wgpu_buffer_unmap(self.buffer_id); - } -} - -struct BufferMapReadAsyncUserData -where - F: FnOnce(BufferMapAsyncResult<&[T]>), -{ - size: u32, - callback: F, - buffer_id: wgn::BufferId, - phantom: std::marker::PhantomData, -} - -struct BufferMapWriteAsyncUserData -where - F: FnOnce(BufferMapAsyncResult<&mut [T]>), -{ - size: u32, - callback: F, - buffer_id: wgn::BufferId, - phantom: std::marker::PhantomData, -} - -impl Buffer { - pub fn map_read_async(&self, start: u32, size: u32, callback: F) - where - T: 'static + Copy, - F: FnOnce(BufferMapAsyncResult<&[T]>) + 'static, - { - let type_size = std::mem::size_of::() as u32; - assert_ne!(type_size, 0); - assert_eq!(size % type_size, 0); - - extern "C" fn buffer_map_read_callback_wrapper( - status: wgn::BufferMapAsyncStatus, - data: *const u8, - user_data: *mut u8, - ) where - F: FnOnce(BufferMapAsyncResult<&[T]>), - { - let user_data = - unsafe { Box::from_raw(user_data as *mut BufferMapReadAsyncUserData) }; - let data = unsafe { - slice::from_raw_parts( - data as *const T, - user_data.size as usize / std::mem::size_of::(), - ) - }; - if let wgn::BufferMapAsyncStatus::Success = status { - (user_data.callback)(Ok(BufferAsyncMapping { - data, - buffer_id: user_data.buffer_id, - })); - } else { - (user_data.callback)(Err(())) - } - } - - let user_data = Box::new(BufferMapReadAsyncUserData { - size, - callback, - buffer_id: self.id, - phantom: std::marker::PhantomData, - }); - wgn::wgpu_buffer_map_read_async( - self.id, - start, - size, - buffer_map_read_callback_wrapper::, - Box::into_raw(user_data) as *mut u8, - ); - } - - pub fn map_write_async(&self, start: u32, size: u32, callback: F) - where - T: 'static + Copy, - F: FnOnce(BufferMapAsyncResult<&mut [T]>) + 'static, - { - let type_size = std::mem::size_of::() as u32; - assert_ne!(type_size, 0); - assert_eq!(size % type_size, 0); - - extern "C" fn buffer_map_write_callback_wrapper( - status: wgn::BufferMapAsyncStatus, - data: *mut u8, - user_data: *mut u8, - ) where - F: FnOnce(BufferMapAsyncResult<&mut [T]>), - { - let user_data = - unsafe { Box::from_raw(user_data as *mut BufferMapWriteAsyncUserData) }; - let data = unsafe { - slice::from_raw_parts_mut( - data as *mut T, - user_data.size as usize / std::mem::size_of::(), - ) - }; - if let wgn::BufferMapAsyncStatus::Success = status { - (user_data.callback)(Ok(BufferAsyncMapping { - data, - buffer_id: user_data.buffer_id, - })); - } else { - (user_data.callback)(Err(())) - } - } - - let user_data = Box::new(BufferMapWriteAsyncUserData { - size, - callback, - buffer_id: self.id, - phantom: std::marker::PhantomData, - }); - wgn::wgpu_buffer_map_write_async( - self.id, - start, - size, - buffer_map_write_callback_wrapper::, - Box::into_raw(user_data) as *mut u8, - ); - } - - pub fn unmap(&self) { - wgn::wgpu_buffer_unmap(self.id); - } -} - -impl Drop for Buffer { - fn drop(&mut self) { - wgn::wgpu_buffer_destroy(self.id); - } -} - -impl Texture { - pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView { - TextureView { - id: wgn::wgpu_texture_create_view(self.id, desc), - owned: true, - } - } - - pub fn create_default_view(&self) -> TextureView { - TextureView { - id: wgn::wgpu_texture_create_default_view(self.id), - owned: true, - } - } -} - -impl Drop for Texture { - fn drop(&mut self) { - if self.owned { - wgn::wgpu_texture_destroy(self.id); - } - } -} - -impl Drop for TextureView { - fn drop(&mut self) { - if self.owned { - wgn::wgpu_texture_view_destroy(self.id); - } - } -} - -impl CommandEncoder { - pub fn finish(self) -> CommandBuffer { - CommandBuffer { - id: wgn::wgpu_command_encoder_finish(self.id), - } - } - - pub fn begin_render_pass(&mut self, desc: &RenderPassDescriptor) -> RenderPass { - let colors = desc - .color_attachments - .iter() - .map(|ca| RenderPassColorAttachmentDescriptor { - attachment: ca.attachment.id, - load_op: ca.load_op, - store_op: ca.store_op, - clear_color: ca.clear_color, - }) - .collect::>(); - - let depth_stencil = desc.depth_stencil_attachment.as_ref().map(|dsa| { - RenderPassDepthStencilAttachmentDescriptor { - attachment: dsa.attachment.id, - depth_load_op: dsa.depth_load_op, - depth_store_op: dsa.depth_store_op, - clear_depth: dsa.clear_depth, - stencil_load_op: dsa.stencil_load_op, - stencil_store_op: dsa.stencil_store_op, - clear_stencil: dsa.clear_stencil, - } - }); - - RenderPass { - id: wgn::wgpu_command_encoder_begin_render_pass( - self.id, - wgn::RenderPassDescriptor { - color_attachments: colors.as_ptr(), - color_attachments_length: colors.len(), - depth_stencil_attachment: depth_stencil - .as_ref() - .map(|at| at as *const _) - .unwrap_or(ptr::null()), - }, - ), - _parent: self, - } - } - - pub fn begin_compute_pass(&mut self) -> ComputePass { - ComputePass { - id: wgn::wgpu_command_encoder_begin_compute_pass(self.id), - _parent: self, - } - } - - pub fn copy_buffer_to_buffer( - &mut self, - source: &Buffer, - source_offset: u32, - destination: &Buffer, - destination_offset: u32, - copy_size: u32, - ) { - wgn::wgpu_command_buffer_copy_buffer_to_buffer( - self.id, - source.id, - source_offset, - destination.id, - destination_offset, - copy_size, - ); - } - - pub fn copy_buffer_to_texture( - &mut self, - source: BufferCopyView, - destination: TextureCopyView, - copy_size: Extent3d, - ) { - wgn::wgpu_command_buffer_copy_buffer_to_texture( - self.id, - &source.into_native(), - &destination.into_native(), - copy_size, - ); - } - - pub fn copy_texture_to_buffer( - &mut self, - source: TextureCopyView, - destination: BufferCopyView, - copy_size: Extent3d, - ) { - wgn::wgpu_command_buffer_copy_texture_to_buffer( - self.id, - &source.into_native(), - &destination.into_native(), - copy_size, - ); - } - - pub fn copy_texture_to_texture( - &mut self, - source: TextureCopyView, - destination: TextureCopyView, - copy_size: Extent3d, - ) { - wgn::wgpu_command_buffer_copy_texture_to_texture( - self.id, - &source.into_native(), - &destination.into_native(), - copy_size, - ); - } -} - -impl<'a> RenderPass<'a> { - pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup, offsets: &[u32]) { - wgn::wgpu_render_pass_set_bind_group( - self.id, - index, - bind_group.id, - offsets.as_ptr(), - offsets.len(), - ); - } - - pub fn set_pipeline(&mut self, pipeline: &RenderPipeline) { - wgn::wgpu_render_pass_set_pipeline(self.id, pipeline.id); - } - - pub fn set_blend_color(&mut self, color: Color) { - wgn::wgpu_render_pass_set_blend_color(self.id, &color); - } - - pub fn set_index_buffer(&mut self, buffer: &Buffer, offset: u32) { - wgn::wgpu_render_pass_set_index_buffer(self.id, buffer.id, offset); - } - - pub fn set_vertex_buffers(&mut self, buffer_pairs: &[(&Buffer, u32)]) { - let mut buffers = Vec::new(); - let mut offsets = Vec::new(); - for &(buffer, offset) in buffer_pairs { - buffers.push(buffer.id); - offsets.push(offset); - } - wgn::wgpu_render_pass_set_vertex_buffers( - self.id, - buffers.as_ptr(), - offsets.as_ptr(), - buffer_pairs.len(), - ); - } - - pub fn set_scissor_rect(&mut self, x: u32, y: u32, w: u32, h: u32) { - wgn::wgpu_render_pass_set_scissor_rect(self.id, x, y, w, h) - } - - pub fn draw(&mut self, vertices: Range, instances: Range) { - wgn::wgpu_render_pass_draw( - self.id, - vertices.end - vertices.start, - instances.end - instances.start, - vertices.start, - instances.start, - ); - } - - pub fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range) { - wgn::wgpu_render_pass_draw_indexed( - self.id, - indices.end - indices.start, - instances.end - instances.start, - indices.start, - base_vertex, - instances.start, - ); - } -} - -impl<'a> Drop for RenderPass<'a> { - fn drop(&mut self) { - wgn::wgpu_render_pass_end_pass(self.id); - } -} - -impl<'a> ComputePass<'a> { - pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup, offsets: &[u32]) { - wgn::wgpu_compute_pass_set_bind_group( - self.id, - index, - bind_group.id, - offsets.as_ptr(), - offsets.len(), - ); - } - - pub fn set_pipeline(&mut self, pipeline: &ComputePipeline) { - wgn::wgpu_compute_pass_set_pipeline(self.id, pipeline.id); - } - - pub fn dispatch(&mut self, x: u32, y: u32, z: u32) { - wgn::wgpu_compute_pass_dispatch(self.id, x, y, z); - } -} - -impl<'a> Drop for ComputePass<'a> { - fn drop(&mut self) { - wgn::wgpu_compute_pass_end_pass(self.id); - } -} - -impl<'a> Queue<'a> { - pub fn submit(&mut self, command_buffers: &[CommandBuffer]) { - self.temp.command_buffers.clear(); - self.temp - .command_buffers - .extend(command_buffers.iter().map(|cb| cb.id)); - - wgn::wgpu_queue_submit( - self.id, - self.temp.command_buffers.as_ptr(), - command_buffers.len(), - ); - } -} - -impl<'a> Drop for SwapChainOutput<'a> { - fn drop(&mut self) { - wgn::wgpu_swap_chain_present(*self.swap_chain_id); - } -} - -impl SwapChain { - pub fn get_next_texture(&mut self) -> SwapChainOutput { - let output = wgn::wgpu_swap_chain_get_next_texture(self.id); - SwapChainOutput { - texture: Texture { - id: output.texture_id, - owned: false, - }, - view: TextureView { - id: output.view_id, - owned: false, - }, - swap_chain_id: &self.id, - } - } -} diff --git a/wgpu-rs/tests/multithreaded_compute.rs b/wgpu-rs/tests/multithreaded_compute.rs deleted file mode 100644 index 76ced61595..0000000000 --- a/wgpu-rs/tests/multithreaded_compute.rs +++ /dev/null @@ -1,100 +0,0 @@ -#[test] -#[cfg(any(feature = "vulkan", feature = "metal", feature = "dx12"))] -fn multithreaded_compute() { - use std::thread; - use std::time::Duration; - use std::sync::mpsc; - - let thread_count = 8; - - let (tx, rx) = mpsc::channel(); - for _ in 0..thread_count { - let tx = tx.clone(); - thread::spawn(move || { - let numbers = vec!(100, 100, 100); - - let size = (numbers.len() * std::mem::size_of::()) as u32; - - let instance = wgpu::Instance::new(); - let adapter = instance.get_adapter(&wgpu::AdapterDescriptor { - power_preference: wgpu::PowerPreference::Default, - }); - let mut device = adapter.create_device(&wgpu::DeviceDescriptor { - extensions: wgpu::Extensions { - anisotropic_filtering: false, - }, - }); - - let cs_bytes = include_bytes!("./../../examples/data/collatz.comp.spv"); - let cs_module = device.create_shader_module(cs_bytes); - - let staging_buffer = device - .create_buffer_mapped( - numbers.len(), - wgpu::BufferUsageFlags::MAP_READ - | wgpu::BufferUsageFlags::TRANSFER_DST - | wgpu::BufferUsageFlags::TRANSFER_SRC, - ) - .fill_from_slice(&numbers); - - let storage_buffer = device.create_buffer(&wgpu::BufferDescriptor { - size, - usage: wgpu::BufferUsageFlags::STORAGE - | wgpu::BufferUsageFlags::TRANSFER_DST - | wgpu::BufferUsageFlags::TRANSFER_SRC, - }); - - let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutBinding { - binding: 0, - visibility: wgpu::ShaderStageFlags::COMPUTE, - ty: wgpu::BindingType::StorageBuffer, - }], - }); - - let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &bind_group_layout, - bindings: &[wgpu::Binding { - binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &storage_buffer, - range: 0..size, - }, - }], - }); - - let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - bind_group_layouts: &[&bind_group_layout], - }); - - let compute_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { - layout: &pipeline_layout, - compute_stage: wgpu::PipelineStageDescriptor { - module: &cs_module, - entry_point: "main", - }, - }); - - let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }); - encoder.copy_buffer_to_buffer(&staging_buffer, 0, &storage_buffer, 0, size); - { - let mut cpass = encoder.begin_compute_pass(); - cpass.set_pipeline(&compute_pipeline); - cpass.set_bind_group(0, &bind_group, &[]); - cpass.dispatch(numbers.len() as u32, 1, 1); - } - encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); - - device.get_queue().submit(&[encoder.finish()]); - - staging_buffer.map_read_async(0, size, |result: wgpu::BufferMapAsyncResult<&[u32]>| { - assert_eq!(result.unwrap().data, [25, 25, 25]); - }); - tx.send(true).unwrap(); - }); - } - - for _ in 0..thread_count { - rx.recv_timeout(Duration::from_secs(10)).expect("A thread never completed."); - } -} From 5eda162748832bcdbc3e1d697d10e69dbee4ddc6 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 10 May 2019 16:22:22 -0400 Subject: [PATCH 2/3] Readme update --- README.md | 42 +++++++++------------------------ etc/gfx-cube.png | Bin 27223 -> 0 bytes etc/gfx-shadow.png | Bin 30306 -> 0 bytes examples/vk_layer_settings.txt | 19 --------------- 4 files changed, 11 insertions(+), 50 deletions(-) delete mode 100644 etc/gfx-cube.png delete mode 100644 etc/gfx-shadow.png delete mode 100644 examples/vk_layer_settings.txt diff --git a/README.md b/README.md index 27cd0e5099..0047d152e0 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,25 @@ +This is an active Github mirror of the WebGPU native implementation in Rust, which now lives in [Mozilla-central](https://hg.mozilla.org/mozilla-central). Issues and pull requests are accepted, but we merge them in m-c manually and then sync to Github instead of landing directly here. + +--- # WebGPU [![Build Status](https://travis-ci.org/gfx-rs/wgpu.svg)](https://travis-ci.org/gfx-rs/wgpu) -[![Crates.io](https://img.shields.io/crates/v/wgpu.svg)](https://crates.io/crates/wgpu) +[![Crates.io](https://img.shields.io/crates/v/wgpu-native.svg?label=wgpu-native)](https://crates.io/crates/wgpu-native) [![Gitter](https://badges.gitter.im/gfx-rs/webgpu.svg)](https://gitter.im/gfx-rs/webgpu) -This is an experimental [WebGPU](https://www.w3.org/community/gpu/) implementation as a native static library. It's written in Rust and is based on [gfx-hal](https://github.com/gfx-rs/gfx) and [satellite](https://github.com/gfx-rs/gfx-memory) libraries. The corresponding WebIDL specification can be found at [gpuweb project](https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs). +This is an experimental [WebGPU](https://www.w3.org/community/gpu/) implementation as a native static library. It's written in Rust and is based on [gfx-hal](https://github.com/gfx-rs/gfx) and [Rendy](https://github.com/amethyst/rendy) libraries. The corresponding WebIDL specification can be found at [gpuweb project](https://github.com/gpuweb/gpuweb/blob/master/spec/index.bs). The implementation consists of the following parts: - - `wgpu-native` - the native implementation of WebGPU as a C API library - - `wgpu-remote` - remoting layer to work with WebGPU across the process boundary - - `wgpu-rs` - idiomatic Rust wrapper of the native library + 1. `wgpu-native` - the native implementation of WebGPU as a C API library + 2. `wgpu-remote` - remoting layer to work with WebGPU across the process boundary + 3. `ffi` - the C headers generated by [cbindgen](https://github.com/eqrion/cbindgen) for both of the libraries Supported platforms: - Vulkan on Windows and Linux - D3D12 and D3D11 on Windows - Metal on macOS and iOS -## Examples +## Usage -![Cube](etc/gfx-cube.png) ![Shadow](etc/gfx-shadow.png) +This repository contains C-language examples that link to the native library targets and perform basic rendering and computation. You can test them with `make`. -To run an example, simply `cd` to the `examples` or `gfx-examples` directory, then use `cargo run` with `--features {backend}` to specify the backend (where `{backend}` is either `vulkan`, `dx12`, `dx11` or `metal`). For example: - -```bash -# Clone the wgpu repository -git clone https://github.com/gfx-rs/wgpu -# Change directory to `examples` -cd wgpu/examples -# Vulkan (Linux/Windows) -cargo run --bin hello_triangle --features vulkan -# Metal (macOS/iOS) -cargo run --bin hello_triangle --features metal -# DirectX12 (Windows) -cargo run --bin hello_triangle --features dx12 - -cd ../gfx-examples -# Vulkan (Linux/Windows) -cargo run --bin cube --features vulkan -# Metal (macOS/iOS) -cargo run --bin cube --features metal -# DirectX12 (Windows) -cargo run --bin cube --features dx12 -``` - -These examples assume that necessary dependencies for the graphics backend are already installed. For more information about installation and usage, refer to the [Getting Started](https://github.com/gfx-rs/gfx/blob/master/info/getting_started.md) gfx-rs guide. +The idiomatic Rust wrapper lives in https://github.com/gfx-rs/wgpu-rs and provides a number of more complex examples to get a feel of the API. diff --git a/etc/gfx-cube.png b/etc/gfx-cube.png deleted file mode 100644 index 339c45b9f99b935d7c7d58284fb3b866f7b82c80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27223 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 diff --git a/etc/gfx-shadow.png b/etc/gfx-shadow.png deleted file mode 100644 index c757a0bdc0374bfde493e159a0a6a30bbdbcde14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30306 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 FV1megL&*RD diff --git a/examples/vk_layer_settings.txt b/examples/vk_layer_settings.txt deleted file mode 100644 index 2b3a1124d4..0000000000 --- a/examples/vk_layer_settings.txt +++ /dev/null @@ -1,19 +0,0 @@ -lunarg_core_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG -lunarg_core_validation.report_flags = error,warn,perf -lunarg_core_validation.log_filename = stdout - -lunarg_object_tracker.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG -lunarg_object_tracker.report_flags = error,warn,perf -lunarg_object_tracker.log_filename = stdout - -lunarg_parameter_validation.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG -lunarg_parameter_validation.report_flags = error,warn,perf -lunarg_parameter_validation.log_filename = stdout - -google_threading.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG -google_threading.report_flags = error,warn,perf -google_threading.log_filename = stdout - -google_unique_objects.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG -google_unique_objects.report_flags = error,warn,perf -google_unique_objects.log_filename = stdout From 540451a66da2097b25e7d328221eb90506279f1d Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 10 May 2019 14:42:48 -0400 Subject: [PATCH 3/3] Fix cbindgen macro expansion and CI --- .travis.yml | 39 ++++++++++++------ Makefile | 4 +- examples/hello_triangle_c/CMakeLists.txt | 6 +-- ffi/wgpu-remote.h | 2 +- ffi/wgpu.h | 51 +++++++++++++++++++++--- wgpu-native/cbindgen.toml | 3 +- wgpu-remote/cbindgen.toml | 4 ++ 7 files changed, 84 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index e6b23e4c97..16b8ecbe42 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: rust +sudo: false +dist: xenial matrix: include: @@ -6,9 +8,11 @@ matrix: - os: linux rust: stable compiler: gcc - - os: linux - rust: nightly - compiler: gcc + #TODO: unlock when libglfw3 on Ubuntu comes with Vulkan support + # or when we add a GL backend. + #- os: linux + # rust: nightly + # compiler: gcc # Windows 64bit - os: windows rust: stable @@ -19,11 +23,11 @@ matrix: rust: stable osx_image: xcode9.4 compiler: clang - #- env: MACOSX_DEPLOYMENT_TARGET=10.9 - # os: osx - # rust: nightly - # osx_image: xcode9.4 - # compiler: clang + - env: MACOSX_DEPLOYMENT_TARGET=10.9 + os: osx + rust: nightly + osx_image: xcode9.4 + compiler: clang # iPhoneOS 64bit #- env: TARGET=aarch64-apple-ios @@ -31,16 +35,27 @@ matrix: # osx_image: xcode9.4 # rust: nightly +addons: + apt: + packages: + - cmake + - libglfw3-dev + homebrew: + update: true + packages: + - cmake + - glfw3 + choco: + packages: + - make + branches: except: - staging.tmp before_install: - # Do not run bors builds against the nightly compiler. - # We want to find out about nightly bugs, so they're done in master, but we don't block on them. - - if [[ $TRAVIS_RUST_VERSION == "nightly" && $TRAVIS_BRANCH == "staging" ]]; then exit; fi - if [[ $TRAVIS_OS_NAME == "windows" ]]; then choco install make; fi script: - cargo test - - if [[ $TRAVIS_OS_NAME == "osx" ]]; then (brew update && brew upgrade cmake && brew install glfw3 && cargo install cbindgen && make ffi-examples); fi + - if [[ $TRAVIS_RUST_VERSION == "nightly" ]]; then cargo +nightly install cbindgen && make VERBOSE=1; fi diff --git a/Makefile b/Makefile index 0c1246ba38..8f5bb9825f 100644 --- a/Makefile +++ b/Makefile @@ -54,10 +54,10 @@ lib-remote: Cargo.lock wgpu-remote/Cargo.toml $(wildcard wgpu-native/**/*.rs wgp cargo build --manifest-path wgpu-remote/Cargo.toml --features $(FEATURE_RUST) ffi/wgpu.h: wgpu-native/cbindgen.toml $(wildcard wgpu-native/**/*.rs) - cbindgen wgpu-native >ffi/wgpu.h + rustup run nightly cbindgen wgpu-native >ffi/wgpu.h ffi/wgpu-remote.h: wgpu-remote/cbindgen.toml $(wildcard wgpu-native/**/*.rs wgpu-remote/**/*.rs) - cbindgen wgpu-remote >ffi/wgpu-remote.h + rustup run nightly cbindgen wgpu-remote >ffi/wgpu-remote.h examples-native: lib-native ffi/wgpu.h examples/hello_triangle_c/main.c cd examples/hello_triangle_c && mkdir -p build && cd build && cmake .. && make diff --git a/examples/hello_triangle_c/CMakeLists.txt b/examples/hello_triangle_c/CMakeLists.txt index 3803b384ed..f3d9d3fca2 100644 --- a/examples/hello_triangle_c/CMakeLists.txt +++ b/examples/hello_triangle_c/CMakeLists.txt @@ -7,17 +7,17 @@ set(TARGET_NAME hello_triangle) add_executable(hello_triangle main.c) if(MSVC) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS) target_compile_options(${TARGET_NAME} PRIVATE /W4) - add_compile_definitions(WGPU_TARGET=WGPU_TARGET_WINDOWS) set(GLFW_LIBRARY glfw3) elseif(APPLE) - add_compile_definitions(WGPU_TARGET=WGPU_TARGET_MACOS) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_MACOS) set(OS_LIBRARIES "-framework Cocoa" "-framework CoreVideo" "-framework IOKit" "-framework QuartzCore") target_compile_options(${TARGET_NAME} PRIVATE -x objective-c) set(GLFW_LIBRARY glfw) else(MSVC) + add_definitions(-DWGPU_TARGET=WGPU_TARGET_LINUX) target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic) - add_compile_definitions(WGPU_TARGET=WGPU_TARGET_LINUX) set(GLFW_LIBRARY glfw) endif(MSVC) diff --git a/ffi/wgpu-remote.h b/ffi/wgpu-remote.h index fe38e949e0..dd528251f5 100644 --- a/ffi/wgpu-remote.h +++ b/ffi/wgpu-remote.h @@ -1,6 +1,6 @@ -/* Generated with cbindgen:0.8.3 */ +/* Generated with cbindgen:0.8.6 */ #include #include diff --git a/ffi/wgpu.h b/ffi/wgpu.h index b427c7c6e1..03c9085cc8 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -1,6 +1,6 @@ +#define WGPU_LOCAL - -/* Generated with cbindgen:0.8.3 */ +/* Generated with cbindgen:0.8.6 */ #include #include @@ -630,7 +630,9 @@ typedef struct { +#if defined(WGPU_LOCAL) WGPUDeviceId wgpu_adapter_create_device(WGPUAdapterId adapter_id, const WGPUDeviceDescriptor *desc); +#endif void wgpu_bind_group_destroy(WGPUBindGroupId bind_group_id); @@ -672,10 +674,14 @@ void wgpu_command_buffer_copy_texture_to_texture(WGPUCommandBufferId command_buf const WGPUTextureCopyView *destination, WGPUExtent3d copy_size); +#if defined(WGPU_LOCAL) WGPUComputePassId wgpu_command_encoder_begin_compute_pass(WGPUCommandEncoderId command_encoder_id); +#endif +#if defined(WGPU_LOCAL) WGPURenderPassId wgpu_command_encoder_begin_render_pass(WGPUCommandEncoderId command_encoder_id, WGPURenderPassDescriptor desc); +#endif WGPUCommandBufferId wgpu_command_encoder_finish(WGPUCommandEncoderId command_encoder_id); @@ -691,42 +697,68 @@ void wgpu_compute_pass_set_bind_group(WGPUComputePassId pass_id, void wgpu_compute_pass_set_pipeline(WGPUComputePassId pass_id, WGPUComputePipelineId pipeline_id); +#if defined(WGPU_LOCAL) WGPUInstanceId wgpu_create_instance(void); +#endif +#if defined(WGPU_LOCAL) WGPUBindGroupId wgpu_device_create_bind_group(WGPUDeviceId device_id, const WGPUBindGroupDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUBindGroupLayoutId wgpu_device_create_bind_group_layout(WGPUDeviceId device_id, const WGPUBindGroupLayoutDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUBufferId wgpu_device_create_buffer(WGPUDeviceId device_id, const WGPUBufferDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUBufferId wgpu_device_create_buffer_mapped(WGPUDeviceId device_id, const WGPUBufferDescriptor *desc, uint8_t **mapped_ptr_out); +#endif +#if defined(WGPU_LOCAL) WGPUCommandEncoderId wgpu_device_create_command_encoder(WGPUDeviceId device_id, const WGPUCommandEncoderDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUComputePipelineId wgpu_device_create_compute_pipeline(WGPUDeviceId device_id, const WGPUComputePipelineDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUPipelineLayoutId wgpu_device_create_pipeline_layout(WGPUDeviceId device_id, const WGPUPipelineLayoutDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPURenderPipelineId wgpu_device_create_render_pipeline(WGPUDeviceId device_id, const WGPURenderPipelineDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUSamplerId wgpu_device_create_sampler(WGPUDeviceId device_id, const WGPUSamplerDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUShaderModuleId wgpu_device_create_shader_module(WGPUDeviceId device_id, const WGPUShaderModuleDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUSwapChainId wgpu_device_create_swap_chain(WGPUDeviceId device_id, WGPUSurfaceId surface_id, const WGPUSwapChainDescriptor *desc); +#endif +#if defined(WGPU_LOCAL) WGPUTextureId wgpu_device_create_texture(WGPUDeviceId device_id, const WGPUTextureDescriptor *desc); +#endif void wgpu_device_destroy(WGPUDeviceId device_id); @@ -734,24 +766,27 @@ WGPUQueueId wgpu_device_get_queue(WGPUDeviceId device_id); void wgpu_device_poll(WGPUDeviceId device_id, bool force_wait); +#if defined(WGPU_LOCAL) WGPUSurfaceId wgpu_instance_create_surface_from_macos_layer(WGPUInstanceId instance_id, void *layer); +#endif +#if defined(WGPU_LOCAL) WGPUSurfaceId wgpu_instance_create_surface_from_windows_hwnd(WGPUInstanceId instance_id, void *hinstance, void *hwnd); - -#if defined(WGPU_WINDOW_WINIT) -WGPUSurfaceId wgpu_instance_create_surface_from_winit(WGPUInstanceId instance_id, - const WGPUWindow *window); #endif +#if defined(WGPU_LOCAL) WGPUSurfaceId wgpu_instance_create_surface_from_xlib(WGPUInstanceId instance_id, const void **display, uint64_t window); +#endif +#if defined(WGPU_LOCAL) WGPUAdapterId wgpu_instance_get_adapter(WGPUInstanceId instance_id, const WGPUAdapterDescriptor *desc); +#endif void wgpu_queue_submit(WGPUQueueId queue_id, const WGPUCommandBufferId *command_buffer_ptr, @@ -801,10 +836,14 @@ WGPUSwapChainOutput wgpu_swap_chain_get_next_texture(WGPUSwapChainId swap_chain_ void wgpu_swap_chain_present(WGPUSwapChainId swap_chain_id); +#if defined(WGPU_LOCAL) WGPUTextureViewId wgpu_texture_create_default_view(WGPUTextureId texture_id); +#endif +#if defined(WGPU_LOCAL) WGPUTextureViewId wgpu_texture_create_view(WGPUTextureId texture_id, const WGPUTextureViewDescriptor *desc); +#endif void wgpu_texture_destroy(WGPUTextureId texture_id); diff --git a/wgpu-native/cbindgen.toml b/wgpu-native/cbindgen.toml index 5ac37d90ee..42a9acb0e6 100644 --- a/wgpu-native/cbindgen.toml +++ b/wgpu-native/cbindgen.toml @@ -1,4 +1,4 @@ -header = "" +header = "#define WGPU_LOCAL" include_version = true braces = "SameLine" line_length = 100 @@ -14,6 +14,7 @@ exclude = ["BufferMapResult"] parse_deps = false [parse.expand] +crates = ["wgpu-native"] features = ["local"] [fn] diff --git a/wgpu-remote/cbindgen.toml b/wgpu-remote/cbindgen.toml index c0c50b493c..ead37a0897 100644 --- a/wgpu-remote/cbindgen.toml +++ b/wgpu-remote/cbindgen.toml @@ -7,11 +7,15 @@ language = "C" [export] prefix = "WGPU" +exclude = ["BufferMapResult"] [parse] parse_deps = true include = ["wgpu_native"] +[parse.expand] +crates = ["wgpu-native"] + [fn] [struct]