From 57b3b72571615b12e5acfb9dcf9fd778bb30304c Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Tue, 9 Jun 2020 13:05:22 -0400 Subject: [PATCH] Implement TEXTURE_BINDING_ARRAY extension --- Cargo.lock | 331 ++++++++++++++++++++------------- player/src/main.rs | 23 ++- wgpu-core/Cargo.toml | 12 +- wgpu-core/src/binding_model.rs | 102 ++-------- wgpu-core/src/conv.rs | 38 ++-- wgpu-core/src/device/mod.rs | 196 ++++++++++++++----- wgpu-core/src/device/trace.rs | 3 +- wgpu-core/src/instance.rs | 14 ++ wgpu-core/src/validation.rs | 57 ++++-- wgpu-types/src/lib.rs | 172 +++++++++++++++++ 10 files changed, 619 insertions(+), 329 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0cc689bdb..d357a06183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,10 +24,10 @@ dependencies = [ ] [[package]] -name = "android_glue" -version = "0.2.3" +name = "android_log-sys" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" +checksum = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e" [[package]] name = "approx" @@ -116,9 +116,9 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "bumpalo" -version = "3.2.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] name = "byteorder" @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.52" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" +checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" [[package]] name = "cfg-if" @@ -160,29 +160,14 @@ dependencies = [ [[package]] name = "cocoa" -version = "0.19.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400" -dependencies = [ - "bitflags", - "block", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4736c86d51bd878b474400d9ec888156f4037015f5d09794fab9f26eab1ad4" +checksum = "8f7b6f3f7f4f0b3ec5c5039aaa9e8c3cef97a7a480a400fd62944841314f293d" dependencies = [ "bitflags", "block", "core-foundation 0.7.0", - "core-graphics 0.19.0", + "core-graphics", "foreign-types", "libc", "objc", @@ -190,9 +175,9 @@ dependencies = [ [[package]] name = "copyless" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" [[package]] name = "core-foundation" @@ -226,18 +211,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" -[[package]] -name = "core-graphics" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" -dependencies = [ - "bitflags", - "core-foundation 0.6.4", - "foreign-types", - "libc", -] - [[package]] name = "core-graphics" version = "0.19.0" @@ -252,13 +225,13 @@ dependencies = [ [[package]] name = "core-video-sys" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc065219542086f72d1e9f7aadbbab0989e980263695d129d502082d063a9d0" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" dependencies = [ "cfg-if", - "core-foundation-sys 0.6.2", - "core-graphics 0.17.3", + "core-foundation-sys 0.7.0", + "core-graphics", "libc", "objc", ] @@ -274,6 +247,17 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "derivative" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" +dependencies = [ + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -282,11 +266,11 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dlib" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" +checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" dependencies = [ - "libloading 0.5.2", + "libloading 0.6.2", ] [[package]] @@ -372,9 +356,9 @@ dependencies = [ [[package]] name = "gfx-auxil" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b46e6f0031330a0be08d17820f2dcaaa91cb36710a97a9500cb4f1c36e785c8" +checksum = "67bdbf8e8d6883c70e5a0d7379ad8ab3ac95127a3761306b36122d8f1c177a8e" dependencies = [ "fxhash", "gfx-hal", @@ -383,9 +367,9 @@ dependencies = [ [[package]] name = "gfx-backend-dx11" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b148219292624126f78245e50a9720d95ea149a415ce8ce73ab7014205301b88" +checksum = "92de0ddc0fde1a89b2a0e92dcc6bbb554bd34af0135e53a28d5ef064611094a4" dependencies = [ "bitflags", "gfx-auxil", @@ -403,9 +387,9 @@ dependencies = [ [[package]] name = "gfx-backend-dx12" -version = "0.5.0" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e526746379e974501551b08958947e67a81b5ea8cdc717a000cdd72577da05" +checksum = "98c598fb38d6f51db0219ac26d16ff8b78bc134987acd1940438a5adc46b694f" dependencies = [ "bitflags", "d3d12", @@ -431,16 +415,16 @@ dependencies = [ [[package]] name = "gfx-backend-metal" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe128c29675b5afc8acdda1dfe096d6abd5e3528059ab0b98bda8215d8beed9" +checksum = "7264b73ea2d8a7cff7eec3a4d08028a96cc18ff2fdf6479fb6f7febbc97dd03f" dependencies = [ "arrayvec", "bitflags", "block", - "cocoa 0.20.0", + "cocoa", "copyless", - "core-graphics 0.19.0", + "core-graphics", "foreign-types", "gfx-auxil", "gfx-hal", @@ -458,14 +442,14 @@ dependencies = [ [[package]] name = "gfx-backend-vulkan" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ff36feae801fa23d29acd74082603a0145a697a23595757dd4e78828ab33da" +checksum = "5a4614727b750d62766db20d94032833f7293f9307f1b2103d5f8833889f863f" dependencies = [ "arrayvec", "ash", "byteorder", - "core-graphics 0.19.0", + "core-graphics", "gfx-hal", "lazy_static", "log", @@ -489,9 +473,9 @@ dependencies = [ [[package]] name = "gfx-hal" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc96180204064c9493e0fe4a9efeb721e0ac59fe8e1906d0c659142a93114fb1" +checksum = "1036da3617426192c1e8453ed2a2b6a66cf1e8c1486a921e9a8d6625234bf53c" dependencies = [ "bitflags", "raw-window-handle", @@ -512,9 +496,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" +checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" dependencies = [ "libc", ] @@ -539,9 +523,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7152d2aed88aa566e7a342250f21ba2222c1ae230ad577499dbfa3c18475b80" +checksum = "7777a24a1ce5de49fcdde84ec46efa487c3af49d5b6e6e0a50367cc5c1096182" [[package]] name = "iovec" @@ -553,10 +537,16 @@ dependencies = [ ] [[package]] -name = "js-sys" -version = "0.3.37" +name = "jni-sys" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce10c23ad2ea25ceca0093bd3192229da4c5b3c0f2de499c1ecac0d98d452177" dependencies = [ "wasm-bindgen", ] @@ -585,9 +575,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.69" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" [[package]] name = "libloading" @@ -601,9 +591,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4f51b790f5bdb65acb4cc94bb81d7b2ee60348a5431ac1467d390b017600b0" +checksum = "2cadb8e769f070c45df05c78c7520eb4cd17061d4ab262e43cfc68b4d00ac71c" dependencies = [ "winapi 0.3.8", ] @@ -694,8 +684,8 @@ checksum = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0" dependencies = [ "bitflags", "block", - "cocoa 0.20.0", - "core-graphics 0.19.0", + "cocoa", + "core-graphics", "foreign-types", "log", "objc", @@ -703,9 +693,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ "cfg-if", "fuchsia-zircon", @@ -757,10 +747,41 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.33" +name = "ndk" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +checksum = "95a356cafe20aee088789830bfea3a61336e84ded9e545e00d3869ce95dcb80c" +dependencies = [ + "jni-sys", + "ndk-sys", + "num_enum", +] + +[[package]] +name = "ndk-glue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1730ee2e3de41c3321160a6da815f008c4006d71b095880ea50e17cf52332b8" +dependencies = [ + "android_log-sys", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2820aca934aba5ed91c79acc72b6a44048ceacc5d36c035ed4e051f12d887d" + +[[package]] +name = "net2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", @@ -802,6 +823,28 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" +dependencies = [ + "proc-macro-crate", + "proc-macro2 1.0.18", + "quote 1.0.7", + "syn", +] + [[package]] name = "objc" version = "0.2.7" @@ -823,9 +866,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" [[package]] name = "ordered-float" @@ -875,8 +918,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb44a25c5bba983be0fc8592dfaf3e6d0935ce8be0c6b15b2a39507af34a926" dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "syn", "synstructure", "unicode-xid 0.2.0", @@ -909,6 +952,15 @@ dependencies = [ "winit", ] +[[package]] +name = "proc-macro-crate" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +dependencies = [ + "toml", +] + [[package]] name = "proc-macro2" version = "0.4.30" @@ -920,9 +972,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.10" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" dependencies = [ "unicode-xid 0.2.0", ] @@ -944,18 +996,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.10", + "proc-macro2 1.0.18", ] [[package]] name = "range-alloc" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5927936723a9e8b715d37d7e4b390455087c4bdf25b9f702309460577b14f9" +checksum = "a871f1e45a3a3f0c73fb60343c811238bb5143a81642e27c2ac7aac27ff01a63" [[package]] name = "raw-window-handle" @@ -974,9 +1026,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "regex" -version = "1.3.7" +version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" dependencies = [ "aho-corasick", "memchr", @@ -986,9 +1038,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "renderdoc" @@ -998,7 +1050,7 @@ checksum = "9c9e8488c98756911664c8cc7b86284c320b6a6357d95908458136d7ebe9280c" dependencies = [ "bitflags", "float-cmp", - "libloading 0.6.1", + "libloading 0.6.2", "once_cell", "renderdoc-sys", "winapi 0.3.8", @@ -1089,21 +1141,21 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.106" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "syn", ] @@ -1137,9 +1189,9 @@ dependencies = [ [[package]] name = "spirv_cross" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946216f8793f7199e3ea5b995ee8dc20a0ace1fcf46293a0ef4c17e1d046dbde" +checksum = "a33a9478e9c78782dd694d05dee074703a9c4c74b511de742b88a7e8149f1b37" dependencies = [ "cc", "js-sys", @@ -1176,23 +1228,23 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.18" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6" dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "unicode-xid 0.2.0", ] [[package]] name = "synstructure" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "syn", "unicode-xid 0.2.0", ] @@ -1215,6 +1267,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + [[package]] name = "typenum" version = "1.12.0" @@ -1245,9 +1306,9 @@ dependencies = [ [[package]] name = "vec_map" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "void" @@ -1268,9 +1329,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.60" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f" +checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1278,37 +1339,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.60" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd" +checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101" dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.60" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4" +checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3" dependencies = [ - "quote 1.0.3", + "quote 1.0.7", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.60" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931" +checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92" dependencies = [ - "proc-macro2 1.0.10", - "quote 1.0.3", + "proc-macro2 1.0.18", + "quote 1.0.7", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -1316,9 +1377,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.60" +version = "0.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639" +checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd" [[package]] name = "wayland-client" @@ -1465,15 +1526,14 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winit" -version = "0.22.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc53342d3d1a3d57f3949e0692d93d5a8adb7814d8683cef4a09c2b550e94246" +checksum = "1e4ccbf7ddb6627828eace16cacde80fc6bf4dbb3469f88487262a02cf8e7862" dependencies = [ - "android_glue", "bitflags", - "cocoa 0.19.1", - "core-foundation 0.6.4", - "core-graphics 0.17.3", + "cocoa", + "core-foundation 0.7.0", + "core-graphics", "core-video-sys", "dispatch", "instant", @@ -1482,6 +1542,9 @@ dependencies = [ "log", "mio", "mio-extras", + "ndk", + "ndk-glue", + "ndk-sys", "objc", "parking_lot", "percent-encoding", diff --git a/player/src/main.rs b/player/src/main.rs index 24daaf569f..3d360eebab 100644 --- a/player/src/main.rs +++ b/player/src/main.rs @@ -254,13 +254,11 @@ impl GlobalExt for wgc::hub::Global { } } A::CreateBindGroupLayout { id, label, entries } => { - let label = Label::new(&label); self.device_create_bind_group_layout::( device, - &wgc::binding_model::BindGroupLayoutDescriptor { - label: label.as_ptr(), - entries: entries.as_ptr(), - entries_length: entries.len(), + &wgt::BindGroupLayoutDescriptor { + label: Some(&label), + bindings: &entries, }, id, ) @@ -294,12 +292,11 @@ impl GlobalExt for wgc::hub::Global { entries, } => { use wgc::binding_model as bm; - let label = Label::new(&label); let entry_vec = entries - .into_iter() + .iter() .map(|(binding, res)| wgc::binding_model::BindGroupEntry { - binding, - resource: match res { + binding: *binding, + resource: match *res { trace::BindingResource::Buffer { id, offset, size } => { bm::BindingResource::Buffer(bm::BufferBinding { buffer: id, @@ -311,6 +308,9 @@ impl GlobalExt for wgc::hub::Global { trace::BindingResource::TextureView(id) => { bm::BindingResource::TextureView(id) } + trace::BindingResource::TextureViewArray(ref id_array) => { + bm::BindingResource::TextureViewArray(id_array) + } }, }) .collect::>(); @@ -318,10 +318,9 @@ impl GlobalExt for wgc::hub::Global { self.device_create_bind_group::( device, &wgc::binding_model::BindGroupDescriptor { - label: label.as_ptr(), + label: Some(&label), layout: layout_id, - entries: entry_vec.as_ptr(), - entries_length: entry_vec.len(), + bindings: &entry_vec, }, id, ); diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index afd7cc3ef5..e7cffb79b0 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -27,7 +27,7 @@ bitflags = "1.0" copyless = "0.1" fxhash = "0.2" log = "0.4" -hal = { package = "gfx-hal", version = "0.5" } +hal = { package = "gfx-hal", version = "0.5.1" } gfx-backend-empty = "0.5" gfx-descriptor = "0.1" gfx-memory = "0.1" @@ -51,16 +51,16 @@ version = "0.5" features = ["peek-poke"] [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] -gfx-backend-metal = { version = "0.5" } -gfx-backend-vulkan = { version = "0.5", optional = true } +gfx-backend-metal = { version = "0.5.3" } +gfx-backend-vulkan = { version = "0.5.7", optional = true } [target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies] -gfx-backend-vulkan = { version = "0.5" } +gfx-backend-vulkan = { version = "0.5.7" } [target.'cfg(windows)'.dependencies] -gfx-backend-dx12 = { version = "0.5" } +gfx-backend-dx12 = { version = "0.5.5" } gfx-backend-dx11 = { version = "0.5" } -gfx-backend-vulkan = { version = "0.5" } +gfx-backend-vulkan = { version = "0.5.7" } [target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "dragonfly", target_os = "freebsd"))'.dependencies] battery = { version = "0.7", optional = true } diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index e94359aa27..74ed59bf05 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -17,83 +17,17 @@ use serde::Deserialize; use serde::Serialize; use std::borrow::Borrow; -#[repr(C)] -#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] -pub enum BindingType { - UniformBuffer = 0, - StorageBuffer = 1, - ReadonlyStorageBuffer = 2, - Sampler = 3, - ComparisonSampler = 4, - SampledTexture = 5, - ReadonlyStorageTexture = 6, - WriteonlyStorageTexture = 7, -} - -#[repr(C)] -#[derive(Clone, Debug, Hash, PartialEq)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] -pub struct BindGroupLayoutEntry { - pub binding: u32, - pub visibility: wgt::ShaderStage, - pub ty: BindingType, - pub multisampled: bool, - pub has_dynamic_offset: bool, - pub view_dimension: wgt::TextureViewDimension, - pub texture_component_type: wgt::TextureComponentType, - pub storage_texture_format: wgt::TextureFormat, -} - -#[derive(Clone, Debug)] -pub enum BindGroupLayoutEntryError { - NoVisibility, - UnexpectedHasDynamicOffset, - UnexpectedMultisampled, -} - -impl BindGroupLayoutEntry { - pub(crate) fn validate(&self) -> Result<(), BindGroupLayoutEntryError> { - if self.visibility.is_empty() { - return Err(BindGroupLayoutEntryError::NoVisibility); - } - match self.ty { - BindingType::UniformBuffer | BindingType::StorageBuffer => {} - _ => { - if self.has_dynamic_offset { - return Err(BindGroupLayoutEntryError::UnexpectedHasDynamicOffset); - } - } - } - match self.ty { - BindingType::SampledTexture => {} - _ => { - if self.multisampled { - return Err(BindGroupLayoutEntryError::UnexpectedMultisampled); - } - } - } - Ok(()) - } -} - -#[repr(C)] -#[derive(Debug)] -pub struct BindGroupLayoutDescriptor { - pub label: *const std::os::raw::c_char, - pub entries: *const BindGroupLayoutEntry, - pub entries_length: usize, -} - #[derive(Clone, Debug)] pub enum BindGroupLayoutError { ConflictBinding(u32), - Entry(u32, BindGroupLayoutEntryError), + MissingExtension(wgt::Extensions), + /// Arrays of bindings can't be 0 elements long + ZeroCount, + /// Arrays of bindings unsupported for this type of binding + ArrayUnsupported, } -pub(crate) type BindEntryMap = FastHashMap; +pub(crate) type BindEntryMap = FastHashMap; #[derive(Debug)] pub struct BindGroupLayout { @@ -135,32 +69,28 @@ pub struct BufferBinding { pub size: wgt::BufferSize, } -#[repr(C)] +// Note: Duplicated in wgpu-rs as BindingResource #[derive(Debug)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] -pub enum BindingResource { +pub enum BindingResource<'a> { Buffer(BufferBinding), Sampler(SamplerId), TextureView(TextureViewId), + TextureViewArray(&'a [TextureViewId]), } -#[repr(C)] +// Note: Duplicated in wgpu-rs as Binding #[derive(Debug)] -#[cfg_attr(feature = "trace", derive(Serialize))] -#[cfg_attr(feature = "replay", derive(Deserialize))] -pub struct BindGroupEntry { +pub struct BindGroupEntry<'a> { pub binding: u32, - pub resource: BindingResource, + pub resource: BindingResource<'a>, } -#[repr(C)] +// Note: Duplicated in wgpu-rs as BindGroupDescriptor #[derive(Debug)] -pub struct BindGroupDescriptor { - pub label: *const std::os::raw::c_char, +pub struct BindGroupDescriptor<'a> { + pub label: Option<&'a str>, pub layout: BindGroupLayoutId, - pub entries: *const BindGroupEntry, - pub entries_length: usize, + pub bindings: &'a [BindGroupEntry<'a>], } #[derive(Debug)] diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 26e449111f..dec551f12d 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::{binding_model, resource, PrivateFeatures}; +use crate::{resource, PrivateFeatures}; pub fn map_buffer_usage(usage: wgt::BufferUsage) -> (hal::buffer::Usage, hal::memory::Properties) { use hal::buffer::Usage as U; @@ -75,40 +75,36 @@ pub fn map_texture_usage( value } -pub fn map_binding_type(binding: &binding_model::BindGroupLayoutEntry) -> hal::pso::DescriptorType { - use crate::binding_model::BindingType as Bt; +pub fn map_binding_type(binding: &wgt::BindGroupLayoutEntry) -> hal::pso::DescriptorType { use hal::pso; + use wgt::BindingType as Bt; match binding.ty { - Bt::UniformBuffer => pso::DescriptorType::Buffer { + Bt::UniformBuffer { dynamic } => pso::DescriptorType::Buffer { ty: pso::BufferDescriptorType::Uniform, format: pso::BufferDescriptorFormat::Structured { - dynamic_offset: binding.has_dynamic_offset, + dynamic_offset: dynamic, }, }, - Bt::StorageBuffer => pso::DescriptorType::Buffer { - ty: pso::BufferDescriptorType::Storage { read_only: false }, + Bt::StorageBuffer { readonly, dynamic } => pso::DescriptorType::Buffer { + ty: pso::BufferDescriptorType::Storage { + read_only: readonly, + }, format: pso::BufferDescriptorFormat::Structured { - dynamic_offset: binding.has_dynamic_offset, + dynamic_offset: dynamic, }, }, - Bt::ReadonlyStorageBuffer => pso::DescriptorType::Buffer { - ty: pso::BufferDescriptorType::Storage { read_only: true }, - format: pso::BufferDescriptorFormat::Structured { - dynamic_offset: binding.has_dynamic_offset, - }, - }, - Bt::Sampler | Bt::ComparisonSampler => pso::DescriptorType::Sampler, - Bt::SampledTexture => pso::DescriptorType::Image { + Bt::Sampler { .. } => pso::DescriptorType::Sampler, + Bt::SampledTexture { .. } => pso::DescriptorType::Image { ty: pso::ImageDescriptorType::Sampled { with_sampler: false, }, }, - Bt::ReadonlyStorageTexture => pso::DescriptorType::Image { - ty: pso::ImageDescriptorType::Storage { read_only: true }, - }, - Bt::WriteonlyStorageTexture => pso::DescriptorType::Image { - ty: pso::ImageDescriptorType::Storage { read_only: false }, + Bt::StorageTexture { readonly, .. } => pso::DescriptorType::Image { + ty: pso::ImageDescriptorType::Storage { + read_only: readonly, + }, }, + _ => unreachable!(), } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 9e5610ec16..6e4a0c9d12 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -37,6 +37,7 @@ mod queue; #[cfg(any(feature = "trace", feature = "replay"))] pub mod trace; +use smallvec::SmallVec; #[cfg(feature = "trace")] use trace::{Action, Trace}; @@ -1083,17 +1084,13 @@ impl Global { pub fn device_create_bind_group_layout( &self, device_id: id::DeviceId, - desc: &binding_model::BindGroupLayoutDescriptor, + desc: &wgt::BindGroupLayoutDescriptor, id_in: Input, ) -> Result { let mut token = Token::root(); let hub = B::hub(self); - let entries = unsafe { slice::from_raw_parts(desc.entries, desc.entries_length) }; let mut entry_map = FastHashMap::default(); - for entry in entries { - if let Err(e) = entry.validate() { - return Err(binding_model::BindGroupLayoutError::Entry(entry.binding, e)); - } + for entry in desc.bindings { if entry_map.insert(entry.binding, entry.clone()).is_some() { return Err(binding_model::BindGroupLayoutError::ConflictBinding( entry.binding, @@ -1115,29 +1112,60 @@ impl Global { } } - let raw_bindings = entries + let (device_guard, mut token) = hub.devices.read(&mut token); + let device = &device_guard[device_id]; + + // Validate the count parameter + for binding in desc + .bindings + .iter() + .filter(|binding| binding.count.is_some()) + { + if let Some(count) = binding.count { + if count == 0 { + return Err(binding_model::BindGroupLayoutError::ZeroCount); + } + match binding.ty { + wgt::BindingType::SampledTexture { .. } => { + if !device + .extensions + .contains(wgt::Extensions::TEXTURE_BINDING_ARRAY) + { + return Err(binding_model::BindGroupLayoutError::MissingExtension( + wgt::Extensions::TEXTURE_BINDING_ARRAY, + )); + } + } + _ => return Err(binding_model::BindGroupLayoutError::ArrayUnsupported), + } + } else { + unreachable!() // programming bug + } + } + + let raw_bindings = desc + .bindings .iter() .map(|binding| hal::pso::DescriptorSetLayoutBinding { binding: binding.binding, ty: conv::map_binding_type(binding), - count: 1, //TODO: consolidate + count: binding + .count + .map_or(1, |v| v as hal::pso::DescriptorArrayIndex), //TODO: consolidate stage_flags: conv::map_shader_stage_flags(binding.visibility), immutable_samplers: false, // TODO }) .collect::>(); //TODO: avoid heap allocation - let (device_guard, mut token) = hub.devices.read(&mut token); - let device = &device_guard[device_id]; let raw = unsafe { let mut raw_layout = device .raw .create_descriptor_set_layout(&raw_bindings, &[]) .unwrap(); - if !desc.label.is_null() { - let label = ffi::CStr::from_ptr(desc.label).to_string_lossy(); + if let Some(label) = desc.label { device .raw - .set_descriptor_set_layout_name(&mut raw_layout, &label); + .set_descriptor_set_layout_name(&mut raw_layout, label); } raw_layout }; @@ -1151,7 +1179,11 @@ impl Global { life_guard: LifeGuard::new(), entries: entry_map, desc_counts: raw_bindings.iter().cloned().collect(), - dynamic_count: entries.iter().filter(|b| b.has_dynamic_offset).count(), + dynamic_count: desc + .bindings + .iter() + .filter(|b| b.has_dynamic_offset()) + .count(), }; let id = hub @@ -1161,8 +1193,8 @@ impl Global { match device.trace { Some(ref trace) => trace.lock().add(trace::Action::CreateBindGroupLayout { id, - label: own_label(&desc.label), - entries: entries.to_owned(), + label: desc.label.map_or_else(String::new, str::to_string), + entries: desc.bindings.to_owned(), }), None => (), }; @@ -1299,8 +1331,7 @@ impl Global { let device = &device_guard[device_id]; let (bind_group_layout_guard, mut token) = hub.bind_group_layouts.read(&mut token); let bind_group_layout = &bind_group_layout_guard[desc.layout]; - let entries = unsafe { slice::from_raw_parts(desc.entries, desc.entries_length) }; - assert_eq!(entries.len(), bind_group_layout.entries.len(), "Bind group has {} entries and bind group layout has {} entries, they should be the same.", entries.len(), bind_group_layout.entries.len()); + assert_eq!(desc.bindings.len(), bind_group_layout.entries.len(), "Bind group has {} entries and bind group layout has {} entries, they should be the same.", desc.bindings.len(), bind_group_layout.entries.len()); let desc_set = unsafe { let mut desc_sets = ArrayVec::<[_; 1]>::new(); @@ -1318,7 +1349,7 @@ impl Global { desc_sets.pop().unwrap() }; - if !desc.label.is_null() { + if let Some(..) = desc.label { //TODO: https://github.com/gfx-rs/gfx-extras/pull/5 //unsafe { // let label = ffi::CStr::from_ptr(desc.label).to_string_lossy(); @@ -1336,34 +1367,31 @@ impl Global { //TODO: group writes into contiguous sections let mut writes = Vec::new(); - for b in entries.iter() { + for b in desc.bindings { let decl = bind_group_layout .entries .get(&b.binding) .expect("Failed to find binding declaration for binding"); - let descriptor = match b.resource { + let descriptors: SmallVec<[_; 1]> = match b.resource { binding_model::BindingResource::Buffer(ref bb) => { let (alignment, pub_usage, internal_use) = match decl.ty { - binding_model::BindingType::UniformBuffer => ( + wgt::BindingType::UniformBuffer { .. } => ( BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::UNIFORM, resource::BufferUse::UNIFORM, ), - binding_model::BindingType::StorageBuffer => ( + wgt::BindingType::StorageBuffer { readonly, .. } => ( BIND_BUFFER_ALIGNMENT, wgt::BufferUsage::STORAGE, - resource::BufferUse::STORAGE_STORE, + if readonly { + resource::BufferUse::STORAGE_STORE + } else { + resource::BufferUse::STORAGE_LOAD + }, ), - binding_model::BindingType::ReadonlyStorageBuffer => ( - BIND_BUFFER_ALIGNMENT, - wgt::BufferUsage::STORAGE, - resource::BufferUse::STORAGE_LOAD, - ), - binding_model::BindingType::Sampler - | binding_model::BindingType::ComparisonSampler - | binding_model::BindingType::SampledTexture - | binding_model::BindingType::ReadonlyStorageTexture - | binding_model::BindingType::WriteonlyStorageTexture => { + wgt::BindingType::Sampler { .. } + | wgt::BindingType::StorageTexture { .. } + | wgt::BindingType::SampledTexture { .. } | _ => { panic!("Mismatched buffer binding type for {:?}. Expected a type of UniformBuffer, StorageBuffer or ReadonlyStorageBuffer", decl) } }; @@ -1402,36 +1430,34 @@ impl Global { Some(bb.size.0) }, }; - hal::pso::Descriptor::Buffer(&buffer.raw, sub_range) + SmallVec::from([hal::pso::Descriptor::Buffer(&buffer.raw, sub_range)]) } binding_model::BindingResource::Sampler(id) => { match decl.ty { - binding_model::BindingType::Sampler - | binding_model::BindingType::ComparisonSampler => {} - _ => panic!("Mismatched sampler binding type in {:?}. Expected a type of Sampler or ComparisonSampler", decl.ty), + wgt::BindingType::Sampler{ .. } => {} + _ => panic!("Mismatched sampler binding type in {:?}. Expected a type of Sampler", decl.ty), } let sampler = used .samplers .use_extend(&*sampler_guard, id, (), ()) .unwrap(); - hal::pso::Descriptor::Sampler(&sampler.raw) + SmallVec::from([hal::pso::Descriptor::Sampler(&sampler.raw)]) } binding_model::BindingResource::TextureView(id) => { let (pub_usage, internal_use, image_layout) = match decl.ty { - binding_model::BindingType::SampledTexture => ( + wgt::BindingType::SampledTexture { .. } => ( wgt::TextureUsage::SAMPLED, resource::TextureUse::SAMPLED, hal::image::Layout::ShaderReadOnlyOptimal, ), - binding_model::BindingType::ReadonlyStorageTexture => ( + wgt::BindingType::StorageTexture { readonly, .. } => ( wgt::TextureUsage::STORAGE, - resource::TextureUse::STORAGE_LOAD, - hal::image::Layout::General, - ), - binding_model::BindingType::WriteonlyStorageTexture => ( - wgt::TextureUsage::STORAGE, - resource::TextureUse::STORAGE_STORE, + if readonly { + resource::TextureUse::STORAGE_LOAD + } else { + resource::TextureUse::STORAGE_STORE + }, hal::image::Layout::General, ), _ => panic!("Mismatched texture binding type in {:?}. Expected a type of SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture", decl), @@ -1463,19 +1489,83 @@ impl Global { pub_usage ); - hal::pso::Descriptor::Image(raw, image_layout) + SmallVec::from([hal::pso::Descriptor::Image(raw, image_layout)]) } resource::TextureViewInner::SwapChain { .. } => { panic!("Unable to create a bind group with a swap chain image") } } } + binding_model::BindingResource::TextureViewArray(ref bindings_array) => { + assert!(device.extensions.contains(wgt::Extensions::TEXTURE_BINDING_ARRAY), "Extension TEXTURE_BINDING_ARRAY must be enabled to use TextureViewArrays in a bind group"); + + if let Some(count) = decl.count { + assert_eq!( + count as usize, + bindings_array.len(), + "Binding count declared with {} items, but {} items were provided", + count, + bindings_array.len() + ); + } else { + panic!( + "Binding declared as a single item, but bind group is using it as an array", + ); + } + + let (pub_usage, internal_use, image_layout) = match decl.ty { + wgt::BindingType::SampledTexture { .. } => ( + wgt::TextureUsage::SAMPLED, + resource::TextureUse::SAMPLED, + hal::image::Layout::ShaderReadOnlyOptimal, + ), + _ => panic!("Mismatched texture binding type in {:?}. Expected a type of SampledTextureArray", decl), + }; + bindings_array + .iter() + .map(|id| { + let view = used + .views + .use_extend(&*texture_view_guard, *id, (), ()) + .unwrap(); + match view.inner { + resource::TextureViewInner::Native { + ref raw, + ref source_id, + } => { + // Careful here: the texture may no longer have its own ref count, + // if it was deleted by the user. + let texture = &texture_guard[source_id.value]; + used.textures + .change_extend( + source_id.value, + &source_id.ref_count, + view.range.clone(), + internal_use, + ) + .unwrap(); + assert!( + texture.usage.contains(pub_usage), + "Texture usage {:?} must contain usage flag(s) {:?}", + texture.usage, + pub_usage + ); + + hal::pso::Descriptor::Image(raw, image_layout) + } + resource::TextureViewInner::SwapChain { .. } => panic!( + "Unable to create a bind group with a swap chain image" + ), + } + }) + .collect() + } }; writes.alloc().init(hal::pso::DescriptorSetWrite { set: desc_set.raw(), binding: b.binding, array_offset: 0, //TODO - descriptors: iter::once(descriptor), + descriptors, }); } @@ -1509,9 +1599,10 @@ impl Global { match device.trace { Some(ref trace) => trace.lock().add(trace::Action::CreateBindGroup { id, - label: own_label(&desc.label), + label: desc.label.map_or_else(String::new, str::to_string), layout_id: desc.layout, - entries: entries + entries: desc + .bindings .iter() .map(|entry| { let res = match entry.resource { @@ -1528,6 +1619,9 @@ impl Global { binding_model::BindingResource::Sampler(id) => { trace::BindingResource::Sampler(id) } + binding_model::BindingResource::TextureViewArray(ref id_array) => { + trace::BindingResource::TextureViewArray(id_array.to_vec()) + } }; (entry.binding, res) }) diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 632136d87f..e45202ae0e 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -27,6 +27,7 @@ pub enum BindingResource { }, Sampler(id::SamplerId), TextureView(id::TextureViewId), + TextureViewArray(Vec), } #[derive(Debug)] @@ -132,7 +133,7 @@ pub enum Action { CreateBindGroupLayout { id: id::BindGroupLayoutId, label: String, - entries: Vec, + entries: Vec, }, DestroyBindGroupLayout(id::BindGroupLayoutId), CreatePipelineLayout { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 0ea5181a06..9271c5c502 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -133,6 +133,10 @@ impl Adapter { wgt::Extensions::ANISOTROPIC_FILTERING, adapter_features.contains(hal::Features::SAMPLER_ANISOTROPY), ); + extensions.set( + wgt::Extensions::TEXTURE_BINDING_ARRAY, + adapter_features.contains(hal::Features::TEXTURE_DESCRIPTOR_ARRAY), + ); if unsafe_extensions.allowed() { // Unsafe extensions go here } @@ -654,6 +658,16 @@ impl Global { { log::warn!("Extension MAPPABLE_PRIMARY_BUFFERS enabled on a discrete gpu. This is a massive performance footgun and likely not what you wanted"); } + if desc + .extensions + .contains(wgt::Extensions::TEXTURE_BINDING_ARRAY) + { + assert!( + available_features.contains(hal::Features::TEXTURE_DESCRIPTOR_ARRAY), + "Missing feature TEXTURE_DESCRIPTOR_ARRAY for texture binding array extension" + ); + enabled_features |= hal::Features::TEXTURE_DESCRIPTOR_ARRAY; + } let family = adapter .raw diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index f46a2ef265..81802fcddd 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -2,11 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use crate::{ - binding_model::{BindEntryMap, BindGroupLayoutEntry, BindingType}, - FastHashMap, -}; +use crate::{binding_model::BindEntryMap, FastHashMap}; use spirv_headers as spirv; +use wgt::{BindGroupLayoutEntry, BindingType}; #[derive(Clone, Debug)] pub enum BindingError { @@ -67,21 +65,41 @@ fn check_binding( } let allowed_usage = match *ty_inner { naga::TypeInner::Struct { .. } => match entry.ty { - BindingType::UniformBuffer => naga::GlobalUse::LOAD, - BindingType::StorageBuffer => naga::GlobalUse::all(), - BindingType::ReadonlyStorageBuffer => naga::GlobalUse::LOAD, + BindingType::UniformBuffer { .. } => naga::GlobalUse::LOAD, + BindingType::StorageBuffer { readonly, .. } => { + if readonly { + naga::GlobalUse::LOAD + } else { + naga::GlobalUse::all() + } + } _ => return Err(BindingError::WrongType), }, naga::TypeInner::Sampler => match entry.ty { - BindingType::Sampler | BindingType::ComparisonSampler => naga::GlobalUse::empty(), + BindingType::Sampler { .. } => naga::GlobalUse::empty(), _ => return Err(BindingError::WrongType), }, naga::TypeInner::Image { base, dim, flags } => { - if entry.multisampled != flags.contains(naga::ImageFlags::MULTISAMPLED) { - return Err(BindingError::WrongTextureMultisampled); + if flags.contains(naga::ImageFlags::MULTISAMPLED) { + match entry.ty { + BindingType::SampledTexture { + multisampled: true, .. + } => {} + _ => return Err(BindingError::WrongTextureMultisampled), + } } + let view_dimension = match entry.ty { + BindingType::SampledTexture { dimension, .. } + | BindingType::StorageTexture { dimension, .. } => dimension, + _ => { + return Err(BindingError::WrongTextureViewDimension { + dim, + is_array: true, + }) + } + }; if flags.contains(naga::ImageFlags::ARRAYED) { - match (dim, entry.view_dimension) { + match (dim, view_dimension) { (spirv::Dim::Dim2D, wgt::TextureViewDimension::D2Array) => (), (spirv::Dim::DimCube, wgt::TextureViewDimension::CubeArray) => (), _ => { @@ -92,7 +110,7 @@ fn check_binding( } } } else { - match (dim, entry.view_dimension) { + match (dim, view_dimension) { (spirv::Dim::Dim1D, wgt::TextureViewDimension::D1) => (), (spirv::Dim::Dim2D, wgt::TextureViewDimension::D2) => (), (spirv::Dim::Dim3D, wgt::TextureViewDimension::D3) => (), @@ -106,8 +124,8 @@ fn check_binding( } } let (allowed_usage, is_sampled) = match entry.ty { - BindingType::SampledTexture => { - let expected_scalar_kind = match entry.texture_component_type { + BindingType::SampledTexture { component_type, .. } => { + let expected_scalar_kind = match component_type { wgt::TextureComponentType::Float => naga::ScalarKind::Float, wgt::TextureComponentType::Sint => naga::ScalarKind::Sint, wgt::TextureComponentType::Uint => naga::ScalarKind::Uint, @@ -124,11 +142,14 @@ fn check_binding( }; (naga::GlobalUse::LOAD, true) } - BindingType::ReadonlyStorageTexture => { - //TODO: check entry.storage_texture_format - (naga::GlobalUse::LOAD, false) + BindingType::StorageTexture { readonly, .. } => { + if readonly { + //TODO: check entry.storage_texture_format + (naga::GlobalUse::LOAD, false) + } else { + (naga::GlobalUse::STORE, false) + } } - BindingType::WriteonlyStorageTexture => (naga::GlobalUse::STORE, false), _ => return Err(BindingError::WrongType), }; if is_sampled != flags.contains(naga::ImageFlags::SAMPLED) { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index e55abe6594..3fd3fb7492 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -134,6 +134,12 @@ bitflags::bitflags! { pub struct Extensions: u64 { /// Allow anisotropic filtering in samplers. /// + /// Supported platforms: + /// - OpenGL 4.6+ (or 1.2+ with widespread GL_EXT_texture_filter_anisotropic) + /// - DX11/12 + /// - Metal + /// - Vulkan + /// /// This is a native only extension. Support is planned to be added to webgpu, /// but it is not yet implemented. /// @@ -146,8 +152,25 @@ bitflags::bitflags! { /// on a system that doesn't, this can severely hinder performance. Only use if you understand /// the consequences. /// + /// Supported platforms: + /// - All + /// /// This is a native only extension. const MAPPABLE_PRIMARY_BUFFERS = 0x0000_0000_0002_0000; + /// Allows the user to create uniform arrays of textures in shaders: + /// + /// eg. `uniform texture2D textures[10]`. + /// + /// This extension only allows them to exist and to be indexed by compile time constant + /// values. + /// + /// Supported platforms: + /// - DX12 + /// - Metal (with MSL 2.0+ on macOS 10.13+) + /// - Vulkan + /// + /// This is a native only extension. + const TEXTURE_BINDING_ARRAY = 0x0000_0000_0004_0000; /// Extensions which are part of the upstream webgpu standard const ALL_WEBGPU = 0x0000_0000_0000_FFFF; /// Extensions that require activating the unsafe extension flag @@ -1127,6 +1150,155 @@ pub struct TextureDataLayout { pub rows_per_image: u32, } +/// Specific type of a binding. +/// WebGPU spec: https://gpuweb.github.io/gpuweb/#dictdef-gpubindgrouplayoutentry +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "trace", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub enum BindingType { + /// A buffer for uniform values. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(std140, binding = 0) + /// uniform Globals { + /// vec2 aUniform; + /// vec2 anotherUniform; + /// }; + /// ``` + UniformBuffer { + /// Indicates that the binding has a dynamic offset. + /// One offset must be passed to [RenderPass::set_bind_group] for each dynamic binding in increasing order of binding number. + dynamic: bool, + }, + /// A storage buffer. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout (set=0, binding=0) buffer myStorageBuffer { + /// vec4 myElement[]; + /// }; + /// ``` + StorageBuffer { + /// Indicates that the binding has a dynamic offset. + /// One offset must be passed to [RenderPass::set_bind_group] for each dynamic binding in increasing order of binding number. + dynamic: bool, + /// The buffer can only be read in the shader and it must be annotated with `readonly`. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout (set=0, binding=0) readonly buffer myStorageBuffer { + /// vec4 myElement[]; + /// }; + /// ``` + readonly: bool, + }, + /// A sampler that can be used to sample a texture. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(binding = 0) + /// uniform sampler s; + /// ``` + Sampler { + /// Use as a comparison sampler instead of a normal sampler. + /// For more info take a look at the analogous functionality in OpenGL: https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode. + comparison: bool, + }, + /// A texture. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(binding = 0) + /// uniform texture2D t; + /// ``` + SampledTexture { + /// Dimension of the texture view that is going to be sampled. + dimension: TextureViewDimension, + /// Component type of the texture. + /// This must be compatible with the format of the texture. + component_type: TextureComponentType, + /// True if the texture has a sample count greater than 1. + multisampled: bool, + }, + /// A storage texture. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(set=0, binding=0, r32f) uniform image2D myStorageImage; + /// ``` + /// Note that the texture format must be specified in the shader as well. + /// A list of valid formats can be found in the specification here: https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.html#layout-qualifiers + StorageTexture { + /// Dimension of the texture view that is going to be sampled. + dimension: TextureViewDimension, + /// Component type of the texture. + /// This must be compatible with the format of the texture. + component_type: TextureComponentType, + /// Format of the texture. + format: TextureFormat, + /// The texture can only be read in the shader and it must be annotated with `readonly`. + /// + /// Example GLSL syntax: + /// ```cpp,ignore + /// layout(set=0, binding=0, r32f) readonly uniform image2D myStorageImage; + /// ``` + readonly: bool, + }, +} + +/// A description of a single binding inside a bind group. +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "trace", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct BindGroupLayoutEntry { + pub binding: u32, + pub visibility: ShaderStage, + pub ty: BindingType, + /// If this value is Some, indicates this entry is an array. Array size must be 1 or greater. + /// + /// If this value is Some and `ty` is `BindingType::SampledTexture`, the TEXTURE_BINDING_ARRAY extension must be enabled. + /// + /// If this value is Some and `ty` is any other variant, bind group creation will fail. + pub count: Option, + /// This struct should be partially initalized using the default method, but binding, visibility, + /// and ty should be set. + pub _non_exhaustive: NonExhaustive, +} + +impl Default for BindGroupLayoutEntry { + fn default() -> Self { + Self { + binding: 0, + visibility: ShaderStage::NONE, + ty: BindingType::UniformBuffer { dynamic: false }, + count: None, + _non_exhaustive: unsafe { NonExhaustive::new() }, + } + } +} + +impl BindGroupLayoutEntry { + pub fn has_dynamic_offset(&self) -> bool { + match self.ty { + BindingType::UniformBuffer { dynamic, .. } + | BindingType::StorageBuffer { dynamic, .. } => dynamic, + _ => false, + } + } +} + +/// A description of a bind group layout. +#[derive(Clone, Debug)] +pub struct BindGroupLayoutDescriptor<'a> { + /// An optional label to apply to the bind group layout. + /// This can be useful for debugging and performance analysis. + pub label: Option<&'a str>, + + pub bindings: &'a [BindGroupLayoutEntry], +} + /// This type allows us to make the serialized representation of a BufferSize more human-readable #[allow(dead_code)] #[cfg_attr(feature = "trace", derive(serde::Serialize))]