diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/metal | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/metal')
56 files changed, 9709 insertions, 0 deletions
diff --git a/third_party/rust/metal/.cargo-checksum.json b/third_party/rust/metal/.cargo-checksum.json new file mode 100644 index 0000000000..e51006b4cc --- /dev/null +++ b/third_party/rust/metal/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.lock":"f310a6965b1650e2a9ff6625e63d1ab6a9ca17164ad6c5287a78ed1959c79deb","Cargo.toml":"9595cec74db3a49b5d0639be9e7d2e1e00891de579b3cee5cfc5dd71fee2e6b6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","Makefile":"6fddc61a94f5b31a65b11c1bef8b19c92bff738716998076c5d49c2834223c75","README.md":"6817e12da257b43352f71f595dcc713adf117c734ebf656e6af2d7d04be27cd6","bors.toml":"187bcd081e215cc861934d2beac27272fa1552c4098a3ec18c797c2c6d3e4d10","examples/argument-buffer/main.rs":"8abbd8444bdcf16113eb8187ff4b173456da08c6c47807ede1c8749acd4c2def","examples/bind/main.rs":"85b15b6edf2da657072ae9df14347cd1333182d74b511e88a5e6a2c1e865a430","examples/caps/main.rs":"145f5efc728232061d12f09ab954f738b6870921ee3f07744ee1450111c98ed8","examples/circle/README.md":"e1c97cf5252f0d1f2934ace78b5d839c5f45911f3007dbd2925eeceefb8f0af6","examples/circle/main.rs":"736ccd51bf6b509f2bc2984de4cba831e27093f7557b14cf08cc318765cddebf","examples/circle/screenshot.png":"97bf07c85bf02367447b9c8a81707c124e4a3b420fa386b95ba08b21938f4f2a","examples/circle/shaders.metal":"5e4f40efca5bb386204a09e1b983cc6c634fdf1ca9dd4974227313adbf50e8b5","examples/circle/shaders.metallib":"666a9491d795ef9c0b9c122c7ada571cc2c0e8774d2d89e5b4b996f3dc47962b","examples/compute/compute-argument-buffer.metal":"6530bbd6a0101d9db2893805436f5dc877959e81ea97a27014c0fc52fc9fa77b","examples/compute/compute-argument-buffer.rs":"dd4df1530e3db407a2da12389f6d76b94c3b998661ad2c2f548dd5efa8e0aa2b","examples/compute/embedded-lib.rs":"f1a9d6c4488eefceb3283965a1bb8868aa1890754968f0dfe387a4a57ab13597","examples/compute/main.rs":"e1849fbda7bba7c532436b56f7808b902810a5f05346030eee0a3fa0eed72fb2","examples/compute/shaders.metal":"f2b15551bb5247b88a3029c3d8ef37c6fa04a4a6cca9f90f069894ed6822b4bf","examples/compute/shaders.metallib":"fef91643e60c0ec99ad2bd2f3916299bcc3e6a80038ea27bed59681badfea7d1","examples/headless-render/README.md":"b1c97b52701cfb41fc0b9e269ba7a7a454d9161746198e2f5789f2636f60842d","examples/headless-render/main.rs":"cf0180839e8d09d4bf403ae947365ac18fa17782172986311bfa04b84f88169e","examples/headless-render/screenshot.png":"01d6ea5791b63b0f01190198756446cf313fc25dc64d0138c1b4f62c9f862dd1","examples/library/main.rs":"a1420ec28a471f28a789b75b3ecf5abb699ed352b337747169914812fb98045a","examples/reflection/main.rs":"927902392a060e40a98f0d222cfa994bb60eee169fdcd550f0ecfc9e44872164","examples/window/README.md":"69655cff298e07887fe70e8a13e27d8a87efcd0cc0da4e15485134e064e1aceb","examples/window/main.rs":"064acd0209e46befbe2b7b7fcb71f7b56f4b36bb7d3f6af464cfd7d71b07aabe","examples/window/screenshot.png":"da7369d7cc297c7f7f6bd773c93e7d708d72442c9c5ff5a20c2f2ee6852552dc","examples/window/shaders.metal":"b83b5faafe43419c6abf4a1d4f2a571c3fdb6bb16feba7136e8735be1a68476c","examples/window/shaders.metallib":"99ffce89e2546210099531301624d02eac87ad8eb107026030a9f72199e5428a","src/argument.rs":"3e3314abfb24545dee802a9dd72291ee4c9c14f1af0292bc492229b3d282fb0a","src/buffer.rs":"86bf6911d5b6f97ec80fd6516cf863655862d68c131d88aa3a39aed546557737","src/capturedescriptor.rs":"ade6513d8c6c99b7ed691a5db1f67e63bd811717808109d4b11f82a8eb36ddab","src/capturemanager.rs":"bdee9e170da371778452513a9ac363a738ea8bfd3f0870d86c6013459c5af010","src/commandbuffer.rs":"2aec88d24f36148fc551fae18c048b5d63f2f671227745670fba59e3ff72089d","src/commandqueue.rs":"5b87621ae4495ae04a5de5ce980d0cde31b4bb0d1e31e932d34c49252240c9d9","src/constants.rs":"7be4d901da863f126d158d1042f5482a122fbcf760f7c225b0b1693a55f6bb4b","src/depthstencil.rs":"ce147f44d856cf7c469b81f97828d03bf2258937d56fffa224ff1e53e12f8ff7","src/device.rs":"43f0f057432a9f3b33228b7d71cb6fa50776fe5a637947a7f72c22c4b0d5e9c7","src/drawable.rs":"03a8adb20da93839314586f0ec12bce139ece546a07e2f9ed60c89303fa52a82","src/encoder.rs":"d08297ebfc13ef81de3f5df4b71fe6d143bf24caab53eca0344d96f0093c3830","src/heap.rs":"27ab954b99a578969111c020ebd8964f82de26cbc5854846003f438828ab3279","src/indirect_encoder.rs":"0210fc65e11061cab9b74c5964141df6304cf28b418ea0112b9ee3cdd13aa535","src/lib.rs":"729551d875aa9e72fe49b907cb635e044c2345680e71a8ab0c24de7233dba839","src/library.rs":"dabc2978fb0272e7a7ecf4ce8cb3adcadd3fd2afece4752d1e2bb42f8e281413","src/pipeline/compute.rs":"0f76ccc1824fdafc4b3ef726aaaa4a3f3dcd63e4fe53dffa8b659ea0ec1fa3d3","src/pipeline/mod.rs":"5ec3cb524cc03202a3394dad5a7d0b733474f664935353253e76a49aed5513ad","src/pipeline/render.rs":"451ab61e6fb2108a2370d2452822ddeae6d7759941bd81175e91afd63a848788","src/renderpass.rs":"163f119c4ae196663336c3327f827623e7e4e5ac16c43e8b2eed0317929521f0","src/resource.rs":"326ff5178144175c28c962d5cf37f0e3db3fb3d0dd15e5509dad123cb3489ca6","src/sampler.rs":"f3a5db9ac05315069c030c3f9a682fe3822447ba3f87d357d73a1b857d91968f","src/texture.rs":"1fbd493af9dcbb5f68b1cad5e9ed15b8d491aa01a433ebff33aa6deb8b3551c1","src/types.rs":"bf4c33c7611a1bcf53c6fae5eff23ca47cf946fb5f9d9325ba0db6436757d9df","src/vertexdescriptor.rs":"b36244b752406769dd0930a607b8f5b9c191b9045e973dd2cce6d85443f318ca"},"package":"5c4e8a431536529327e28c9ba6992f2cb0c15d4222f0602a16e6d7695ff3bccf"}
\ No newline at end of file diff --git a/third_party/rust/metal/Cargo.lock b/third_party/rust/metal/Cargo.lock new file mode 100644 index 0000000000..4017d7463a --- /dev/null +++ b/third_party/rust/metal/Cargo.lock @@ -0,0 +1,1070 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adler32" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "andrew" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rusttype 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "android_log-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "approx" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayvec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "calloop" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cocoa" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cocoa" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "core-foundation-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "core-graphics" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-graphics" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cty" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "derivative" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "dlib" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "downcast-rs" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "instant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazycell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.72" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libloading" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "line_drawing" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lock_api" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "metal" +version = "0.20.0" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cty 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "png 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)", + "sema 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winit 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ndk" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_enum 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ndk-glue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "android_log-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ndk-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_enum" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derivative 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_enum_derive 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num_enum_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-crate 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "objc_exception" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ordered-float" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "png" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "deflate 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rusttype" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rusttype 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rusttype" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sema" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde" +version = "1.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smallvec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smithay-client-toolkit" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-protocols 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stb_truetype" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.114 (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 = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-client" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "calloop 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-scanner 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-sys 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-commons" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-sys 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-protocols" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-scanner 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-scanner" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wayland-sys" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winit" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cocoa 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-video-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk-glue 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ndk-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smithay-client-toolkit 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "x11-dl" +version = "2.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "xml-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" +"checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +"checksum android_log-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e" +"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +"checksum calloop 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" +"checksum cc 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c" +"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum cocoa 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a4736c86d51bd878b474400d9ec888156f4037015f5d09794fab9f26eab1ad4" +"checksum cocoa 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c54201c07dcf3a5ca33fececb8042aed767ee4bfd5a0235a8ceabcda956044b2" +"checksum cocoa-foundation 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +"checksum core-foundation 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb" +"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +"checksum core-foundation-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6" +"checksum core-graphics 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59e78b2e0aaf43f08e7ae0d6bc96895ef72ff0921c7d4ff4762201b2dba376dd" +"checksum core-graphics 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6082396a349fa49674ba1bda4077332a18bf150e8fa75745ece07085e29a113" +"checksum core-graphics-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e92f5d519093a4178296707dbaa3880eae85a5ef5386675f361a1cf25376e93c" +"checksum core-video-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +"checksum cty 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7313c0d620d0cb4dbd9d019e461a4beb501071ff46ec0ab933efb4daa76d73e3" +"checksum deflate 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +"checksum derivative 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f" +"checksum dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" +"checksum downcast-rs 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "18df8ce4470c189d18aa926022da57544f31e154631eb4cfe796aea97051fe6c" +"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" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c346c299e3fe8ef94dc10c2c0253d858a69aac1245157a3bf4125915d528caf" +"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +"checksum jni-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122" +"checksum libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)" = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" +"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" +"checksum line_drawing 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" +"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +"checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +"checksum miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum ndk 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a356cafe20aee088789830bfea3a61336e84ded9e545e00d3869ce95dcb80c" +"checksum ndk-glue 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d1730ee2e3de41c3321160a6da815f008c4006d71b095880ea50e17cf52332b8" +"checksum ndk-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2820aca934aba5ed91c79acc72b6a44048ceacc5d36c035ed4e051f12d887d" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum num_enum 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4" +"checksum num_enum_derive 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d" +"checksum objc 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "31d20fd2b37e07cf5125be68357b588672e8cefe9a96f8c17a9d46053b3e590d" +"checksum objc_exception 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "098cd29a2fa3c230d3463ae069cecccc3fdfd64c0d2496ab5b96f82dab6a00dc" +"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" +"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" +"checksum png 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970" +"checksum proc-macro-crate 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" +"checksum raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum rusttype 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +"checksum rusttype 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "14a911032fb5791ccbeec9f28fdcb9bf0983b81f227bafdfd227c658d0731c8a" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +"checksum sema 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3af15ff9b4a7d4bd2b21222c05154ee58260780a4d492c22de810f4f4187832" +"checksum serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" +"checksum smithay-client-toolkit 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" +"checksum stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +"checksum syn 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +"checksum wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" +"checksum wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" +"checksum wayland-protocols 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" +"checksum wayland-scanner 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +"checksum wayland-sys 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum winit 0.22.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ccbf7ddb6627828eace16cacde80fc6bf4dbb3469f88487262a02cf8e7862" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +"checksum x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" +"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" diff --git a/third_party/rust/metal/Cargo.toml b/third_party/rust/metal/Cargo.toml new file mode 100644 index 0000000000..5ab3c77ca2 --- /dev/null +++ b/third_party/rust/metal/Cargo.toml @@ -0,0 +1,100 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +edition = "2018" +name = "metal" +version = "0.20.0" +authors = ["GFX Developers"] +exclude = ["guide/**/*", "examples/texture/**/*", "tests/**/*", "Cargo.lock", "target/**/*"] +description = "Rust bindings for Metal" +homepage = "https://github.com/gfx-rs/metal-rs" +documentation = "https://docs.rs/crate/metal" +readme = "README.md" +keywords = ["metal", "graphics", "bindings"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/gfx-rs/metal-rs" +[package.metadata.docs.rs] +default-target = "x86_64-apple-darwin" + +[[example]] +name = "window" + +[[example]] +name = "headless-render" + +[[example]] +name = "library" + +[[example]] +name = "reflection" + +[[example]] +name = "caps" + +[[example]] +name = "argument-buffer" + +[[example]] +name = "circle" +path = "examples/circle/main.rs" + +[[example]] +name = "compute" +path = "examples/compute/main.rs" + +[[example]] +name = "embedded-lib" +path = "examples/compute/embedded-lib.rs" + +[[example]] +name = "compute-argument-buffer" +path = "examples/compute/compute-argument-buffer.rs" + +[[example]] +name = "bind" +[dependencies.bitflags] +version = "1" + +[dependencies.block] +version = "0.1.5" + +[dependencies.cocoa-foundation] +version = "0.1" + +[dependencies.foreign-types] +version = "0.3" + +[dependencies.log] +version = "0.4" + +[dependencies.objc] +version = "0.2.4" +features = ["objc_exception"] +[dev-dependencies.cocoa] +version = "0.23" + +[dev-dependencies.cty] +version = "0.2.1" + +[dev-dependencies.png] +version = "0.16" + +[dev-dependencies.sema] +version = "0.1.4" + +[dev-dependencies.winit] +version = "0.22" + +[features] +default = [] +private = [] diff --git a/third_party/rust/metal/LICENSE-APACHE b/third_party/rust/metal/LICENSE-APACHE new file mode 100644 index 0000000000..16fe87b06e --- /dev/null +++ b/third_party/rust/metal/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/metal/LICENSE-MIT b/third_party/rust/metal/LICENSE-MIT new file mode 100644 index 0000000000..25597d5838 --- /dev/null +++ b/third_party/rust/metal/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2010 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/metal/Makefile b/third_party/rust/metal/Makefile new file mode 100644 index 0000000000..bc35876945 --- /dev/null +++ b/third_party/rust/metal/Makefile @@ -0,0 +1,12 @@ + +compute: + xcrun -sdk macosx metal -c examples/compute/shaders.metal -o examples/compute/shaders.air + xcrun -sdk macosx metallib examples/compute/shaders.air -o examples/compute/shaders.metallib + +window: + xcrun -sdk macosx metal -c examples/window/shaders.metal -o examples/window/shaders.air + xcrun -sdk macosx metallib examples/window/shaders.air -o examples/window/shaders.metallib + +circle: + xcrun -sdk macosx metal -c examples/circle/shaders.metal -o examples/circle/shaders.air + xcrun -sdk macosx metallib examples/circle/shaders.air -o examples/circle/shaders.metallib diff --git a/third_party/rust/metal/README.md b/third_party/rust/metal/README.md new file mode 100644 index 0000000000..7fac036e5f --- /dev/null +++ b/third_party/rust/metal/README.md @@ -0,0 +1,32 @@ +# metal-rs +[![Actions Status](https://github.com/gfx-rs/metal-rs/workflows/ci/badge.svg)](https://github.com/gfx-rs/metal-rs/actions) +[![Crates.io](https://img.shields.io/crates/v/metal.svg?label=metal)](https://crates.io/crates/metal) + +Unsafe Rust bindings for the Metal 3D Graphics API. + +## Examples + +The [examples](/examples) directory highlights different ways of using the Metal graphics API for rendering +and computation. + +Examples can be run using commands such as: + +``` +# Replace `window` with the name of the example that you would like to run +cargo run --example window +``` + +## License + +Licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/third_party/rust/metal/bors.toml b/third_party/rust/metal/bors.toml new file mode 100644 index 0000000000..bb41b7ae97 --- /dev/null +++ b/third_party/rust/metal/bors.toml @@ -0,0 +1,8 @@ +status = [ "Build" ] + +# As of May 2020 we can expect CI to take roughly 3 minutes based on +# Based on https://github.com/chinedufn/metal-rs/actions/runs/94020785 +# +# We round this up to a timeout of 5 minutes to account for any potential future +# inconsistencies in CI run times. +timeout-sec = 300 diff --git a/third_party/rust/metal/examples/argument-buffer/main.rs b/third_party/rust/metal/examples/argument-buffer/main.rs new file mode 100644 index 0000000000..2ab1346ab1 --- /dev/null +++ b/third_party/rust/metal/examples/argument-buffer/main.rs @@ -0,0 +1,43 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +fn main() { + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + + let device = Device::system_default().expect("no device found"); + + let desc1 = ArgumentDescriptor::new(); + desc1.set_data_type(MTLDataType::Texture); + let desc2 = ArgumentDescriptor::new(); + desc2.set_data_type(MTLDataType::Sampler); + desc2.set_index(1); + + let encoder = device.new_argument_encoder(&Array::from_slice(&[desc1, desc2])); + println!("{:?}", encoder); + + let buffer = device.new_buffer(encoder.encoded_length(), MTLResourceOptions::empty()); + encoder.set_argument_buffer(&buffer, 0); + + let sampler = { + let descriptor = SamplerDescriptor::new(); + descriptor.set_support_argument_buffers(true); + device.new_sampler(&descriptor) + }; + encoder.set_sampler_state(1, &sampler); + println!("{:?}", sampler); + + unsafe { + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/bind/main.rs b/third_party/rust/metal/examples/bind/main.rs new file mode 100644 index 0000000000..908aefcb41 --- /dev/null +++ b/third_party/rust/metal/examples/bind/main.rs @@ -0,0 +1,42 @@ +// Copyright 2018 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +fn main() { + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + + let device = Device::system_default().expect("no device found"); + + let buffer = device.new_buffer(4, MTLResourceOptions::empty()); + let sampler = { + let descriptor = SamplerDescriptor::new(); + device.new_sampler(&descriptor) + }; + + let queue = device.new_command_queue(); + let cmd_buf = queue.new_command_buffer(); + + let encoder = cmd_buf.new_compute_command_encoder(); + + encoder.set_buffers(2, &[Some(&buffer), None], &[4, 0]); + encoder.set_sampler_states(1, &[Some(&sampler), None]); + + encoder.end_encoding(); + cmd_buf.commit(); + + println!("Everything is bound"); + + unsafe { + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/caps/main.rs b/third_party/rust/metal/examples/caps/main.rs new file mode 100644 index 0000000000..76030954ef --- /dev/null +++ b/third_party/rust/metal/examples/caps/main.rs @@ -0,0 +1,32 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use metal::*; + +fn main() { + let device = Device::system_default().expect("no device found"); + + #[cfg(feature = "private")] + { + println!("Vendor: {:?}", unsafe { device.vendor() }); + println!("Family: {:?}", unsafe { device.family_name() }); + } + println!( + "Max threads per threadgroup: {:?}", + device.max_threads_per_threadgroup() + ); + #[cfg(target_os = "macos")] + { + println!("Integrated GPU: {:?}", device.is_low_power()); + println!("Headless: {:?}", device.is_headless()); + println!("D24S8: {:?}", device.d24_s8_supported()); + } + println!( + "Indirect argument buffer: {:?}", + device.argument_buffers_support() + ); +} diff --git a/third_party/rust/metal/examples/circle/README.md b/third_party/rust/metal/examples/circle/README.md new file mode 100644 index 0000000000..f51853ac38 --- /dev/null +++ b/third_party/rust/metal/examples/circle/README.md @@ -0,0 +1,11 @@ +## circle + +Renders a circle in a window. As metal primitive types are only limited to point, line and triangle shape, this example shows how we can form complex structures out of primitive types. + +![Screenshot of the final render](./screenshot.png) + +## To Run + +``` +cargo run --example circle +``` diff --git a/third_party/rust/metal/examples/circle/main.rs b/third_party/rust/metal/examples/circle/main.rs new file mode 100644 index 0000000000..70a7d22668 --- /dev/null +++ b/third_party/rust/metal/examples/circle/main.rs @@ -0,0 +1,215 @@ +use metal::*; + +use winit::platform::macos::WindowExtMacOS; +use winit::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, +}; + +use cocoa::{appkit::NSView, base::id as cocoa_id}; + +use objc::runtime::YES; + +use std::mem; + +// Declare the data structures needed to carry vertex layout to +// metal shading language(MSL) program. Use #[repr(C)], to make +// the data structure compatible with C++ type data structure +// for vertex defined in MSL program as MSL program is broadly +// based on C++ +#[repr(C)] +#[derive(Debug)] +pub struct position(cty::c_float, cty::c_float); +#[repr(C)] +#[derive(Debug)] +pub struct color(cty::c_float, cty::c_float, cty::c_float); +#[repr(C)] +#[derive(Debug)] +pub struct AAPLVertex { + p: position, + c: color, +} + +fn main() { + // Create a window for viewing the content + let event_loop = EventLoop::new(); + let events_loop = winit::event_loop::EventLoop::new(); + let size = winit::dpi::LogicalSize::new(800, 600); + + let window = winit::window::WindowBuilder::new() + .with_inner_size(size) + .with_title("Metal".to_string()) + .build(&events_loop) + .unwrap(); + + // Set up the GPU device found in the system + let device = Device::system_default().expect("no device found"); + println!("Your device is: {}", device.name(),); + + let library_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("examples/circle/shaders.metallib"); + + // Use the metallib file generated out of .metal shader file + let library = device.new_library_with_file(library_path).unwrap(); + + // The render pipeline generated from the vertex and fragment shaders in the .metal shader file. + let pipeline_state = prepare_pipeline_state(&device, &library); + + // Set the command queue used to pass commands to the device. + let command_queue = device.new_command_queue(); + + // Currently, CoreAnimationLayer is the only interface that provide + // layers to carry drawable texture from GPU rendaring through metal + // library to viewable windows. + let layer = CoreAnimationLayer::new(); + layer.set_device(&device); + layer.set_pixel_format(MTLPixelFormat::BGRA8Unorm); + layer.set_presents_with_transaction(false); + + unsafe { + let view = window.ns_view() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } + + let draw_size = window.inner_size(); + layer.set_drawable_size(CGSize::new(draw_size.width as f64, draw_size.height as f64)); + + let vbuf = { + let vertex_data = create_vertex_points_for_circle(); + let vertex_data = vertex_data.as_slice(); + + device.new_buffer_with_data( + vertex_data.as_ptr() as *const _, + (vertex_data.len() * mem::size_of::<AAPLVertex>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache | MTLResourceOptions::StorageModeManaged, + ) + }; + + event_loop.run(move |event, _, control_flow| { + // ControlFlow::Wait pauses the event loop if no events are available to process. + // This is ideal for non-game applications that only update in response to user + // input, and uses significantly less power/CPU time than ControlFlow::Poll. + *control_flow = ControlFlow::Wait; + + match event { + Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } => { + println!("The close button was pressed; stopping"); + *control_flow = ControlFlow::Exit + } + Event::MainEventsCleared => { + // Queue a RedrawRequested event. + window.request_redraw(); + } + Event::RedrawRequested(_) => { + // It's preferrable to render in this event rather than in MainEventsCleared, since + // rendering in here allows the program to gracefully handle redraws requested + // by the OS. + let drawable = match layer.next_drawable() { + Some(drawable) => drawable, + None => return, + }; + + // Create a new command buffer for each render pass to the current drawable + let command_buffer = command_queue.new_command_buffer(); + + // Obtain a renderPassDescriptor generated from the view's drawable textures. + let render_pass_descriptor = RenderPassDescriptor::new(); + prepare_render_pass_descriptor(&render_pass_descriptor, drawable.texture()); + + // Create a render command encoder. + let encoder = command_buffer.new_render_command_encoder(&render_pass_descriptor); + encoder.set_render_pipeline_state(&pipeline_state); + // Pass in the parameter data. + encoder.set_vertex_buffer(0, Some(&vbuf), 0); + // Draw the triangles which will eventually form the circle. + encoder.draw_primitives(MTLPrimitiveType::TriangleStrip, 0, 1080); + encoder.end_encoding(); + + // Schedule a present once the framebuffer is complete using the current drawable. + command_buffer.present_drawable(&drawable); + + // Finalize rendering here & push the command buffer to the GPU. + command_buffer.commit(); + } + _ => (), + } + }); +} + +// If we want to draw a circle, we need to draw it out of the three primitive +// types available with metal framework. Triangle is used in this case to form +// the circle. If we consider a circle to be total of 360 degree at center, we +// can form small triangle with one point at origin and two points at the +// perimeter of the circle for each degree. Eventually, if we can take enough +// triangle virtices for total of 360 degree, the triangles together will +// form a circle. This function captures the triangle vertices for each degree +// and push the co-ordinates of the vertices to a rust vector +fn create_vertex_points_for_circle() -> Vec<AAPLVertex> { + let mut v: Vec<AAPLVertex> = Vec::new(); + let origin_x: f32 = 0.0; + let origin_y: f32 = 0.0; + + // Size of the circle + let circle_size = 0.8f32; + + for i in 0..720 { + let y = i as f32; + // Get the X co-ordinate of each point on the perimeter of circle + let position_x: f32 = y.to_radians().cos() * 100.0; + let position_x: f32 = position_x.trunc() / 100.0; + // Set the size of the circle + let position_x: f32 = position_x * circle_size; + // Get the Y co-ordinate of each point on the perimeter of circle + let position_y: f32 = y.to_radians().sin() * 100.0; + let position_y: f32 = position_y.trunc() / 100.0; + // Set the size of the circle + let position_y: f32 = position_y * circle_size; + + v.push(AAPLVertex { + p: position(position_x, position_y), + c: color(0.7, 0.3, 0.5), + }); + + if (i + 1) % 2 == 0 { + // For each two points on perimeter, push one point of origin + v.push(AAPLVertex { + p: position(origin_x, origin_y), + c: color(0.2, 0.7, 0.4), + }); + } + } + + v +} + +fn prepare_render_pass_descriptor(descriptor: &RenderPassDescriptorRef, texture: &TextureRef) { + let color_attachment = descriptor.color_attachments().object_at(0).unwrap(); + + color_attachment.set_texture(Some(texture)); + color_attachment.set_load_action(MTLLoadAction::Clear); + // Setting a background color + color_attachment.set_clear_color(MTLClearColor::new(0.5, 0.5, 0.8, 1.0)); + color_attachment.set_store_action(MTLStoreAction::Store); +} + +fn prepare_pipeline_state(device: &Device, library: &Library) -> RenderPipelineState { + let vert = library.get_function("vs", None).unwrap(); + let frag = library.get_function("ps", None).unwrap(); + + let pipeline_state_descriptor = RenderPipelineDescriptor::new(); + pipeline_state_descriptor.set_vertex_function(Some(&vert)); + pipeline_state_descriptor.set_fragment_function(Some(&frag)); + pipeline_state_descriptor + .color_attachments() + .object_at(0) + .unwrap() + .set_pixel_format(MTLPixelFormat::BGRA8Unorm); + + device + .new_render_pipeline_state(&pipeline_state_descriptor) + .unwrap() +} diff --git a/third_party/rust/metal/examples/circle/screenshot.png b/third_party/rust/metal/examples/circle/screenshot.png Binary files differnew file mode 100644 index 0000000000..38f86e733d --- /dev/null +++ b/third_party/rust/metal/examples/circle/screenshot.png diff --git a/third_party/rust/metal/examples/circle/shaders.metal b/third_party/rust/metal/examples/circle/shaders.metal new file mode 100644 index 0000000000..037af8a233 --- /dev/null +++ b/third_party/rust/metal/examples/circle/shaders.metal @@ -0,0 +1,39 @@ +#include <metal_stdlib> + +#include <simd/simd.h> + +using namespace metal; + +typedef struct { + float x; + float y; +}position; + +typedef struct { + float r; + float g; + float b; +}color; + +typedef struct { + position p; + color c; +}AAPLVertex; + +struct ColorInOut { + float4 position[[position]]; + float4 color; +}; + +vertex ColorInOut vs(constant AAPLVertex * vertex_array[[buffer(0)]], unsigned int vid[[vertex_id]]) { + ColorInOut out; + + out.position = float4(float2(vertex_array[vid].p.x, vertex_array[vid].p.y), 0.0, 1.0); + out.color = float4(float3(vertex_array[vid].c.r, vertex_array[vid].c.g, vertex_array[vid].c.b), 1.0); + + return out; +} + +fragment float4 ps(ColorInOut in [[stage_in]]) { + return in.color; +} diff --git a/third_party/rust/metal/examples/circle/shaders.metallib b/third_party/rust/metal/examples/circle/shaders.metallib Binary files differnew file mode 100644 index 0000000000..cbb9bc5e5a --- /dev/null +++ b/third_party/rust/metal/examples/circle/shaders.metallib diff --git a/third_party/rust/metal/examples/compute/compute-argument-buffer.metal b/third_party/rust/metal/examples/compute/compute-argument-buffer.metal new file mode 100644 index 0000000000..1dcc79daf5 --- /dev/null +++ b/third_party/rust/metal/examples/compute/compute-argument-buffer.metal @@ -0,0 +1,14 @@ +#include <metal_stdlib> + +using namespace metal; + +struct SumInput { + device uint *data; + volatile device atomic_uint *sum; +}; + +kernel void sum(device SumInput& input [[ buffer(0) ]], + uint gid [[ thread_position_in_grid ]]) +{ + atomic_fetch_add_explicit(input.sum, input.data[gid], memory_order_relaxed); +} diff --git a/third_party/rust/metal/examples/compute/compute-argument-buffer.rs b/third_party/rust/metal/examples/compute/compute-argument-buffer.rs new file mode 100644 index 0000000000..be554b1cc1 --- /dev/null +++ b/third_party/rust/metal/examples/compute/compute-argument-buffer.rs @@ -0,0 +1,101 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +use std::mem; + +static LIBRARY_SRC: &str = include_str!("compute-argument-buffer.metal"); + +fn main() { + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + let device = Device::system_default().expect("no device found"); + let command_queue = device.new_command_queue(); + + let data = [ + 1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, + ]; + + let buffer = device.new_buffer_with_data( + unsafe { mem::transmute(data.as_ptr()) }, + (data.len() * mem::size_of::<u32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache, + ); + + let sum = { + let data = [0u32]; + device.new_buffer_with_data( + unsafe { mem::transmute(data.as_ptr()) }, + (data.len() * mem::size_of::<u32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache, + ) + }; + + let command_buffer = command_queue.new_command_buffer(); + let encoder = command_buffer.new_compute_command_encoder(); + + let library = device + .new_library_with_source(LIBRARY_SRC, &CompileOptions::new()) + .unwrap(); + let kernel = library.get_function("sum", None).unwrap(); + + let argument_encoder = kernel.new_argument_encoder(0); + let arg_buffer = device.new_buffer( + argument_encoder.encoded_length(), + MTLResourceOptions::empty(), + ); + argument_encoder.set_argument_buffer(&arg_buffer, 0); + argument_encoder.set_buffer(0, &buffer, 0); + argument_encoder.set_buffer(1, &sum, 0); + + let pipeline_state_descriptor = ComputePipelineDescriptor::new(); + pipeline_state_descriptor.set_compute_function(Some(&kernel)); + + let pipeline_state = device + .new_compute_pipeline_state_with_function( + pipeline_state_descriptor.compute_function().unwrap(), + ) + .unwrap(); + + encoder.set_compute_pipeline_state(&pipeline_state); + encoder.set_buffer(0, Some(&arg_buffer), 0); + + encoder.use_resource(&buffer, MTLResourceUsage::Read); + encoder.use_resource(&sum, MTLResourceUsage::Write); + + let width = 16; + + let thread_group_count = MTLSize { + width, + height: 1, + depth: 1, + }; + + let thread_group_size = MTLSize { + width: (data.len() as u64 + width) / width, + height: 1, + depth: 1, + }; + + encoder.dispatch_thread_groups(thread_group_count, thread_group_size); + encoder.end_encoding(); + command_buffer.commit(); + command_buffer.wait_until_completed(); + + let ptr = sum.contents() as *mut u32; + + unsafe { + assert_eq!(465, *ptr); + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/compute/embedded-lib.rs b/third_party/rust/metal/examples/compute/embedded-lib.rs new file mode 100644 index 0000000000..7ed61f7207 --- /dev/null +++ b/third_party/rust/metal/examples/compute/embedded-lib.rs @@ -0,0 +1,31 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +fn main() { + let library_data = include_bytes!("shaders.metallib"); + + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + let device = Device::system_default().expect("no device found"); + + let library = device.new_library_with_data(&library_data[..]).unwrap(); + let kernel = library.get_function("sum", None).unwrap(); + + println!("Function name: {}", kernel.name()); + println!("Function type: {:?}", kernel.function_type()); + println!("OK"); + + unsafe { + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/compute/main.rs b/third_party/rust/metal/examples/compute/main.rs new file mode 100644 index 0000000000..efc930d8ca --- /dev/null +++ b/third_party/rust/metal/examples/compute/main.rs @@ -0,0 +1,97 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +use std::mem; + +fn main() { + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + let device = Device::system_default().expect("no device found"); + let command_queue = device.new_command_queue(); + + let data = [ + 1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, + ]; + + let buffer = device.new_buffer_with_data( + unsafe { mem::transmute(data.as_ptr()) }, + (data.len() * mem::size_of::<u32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache, + ); + + let sum = { + let data = [0u32]; + device.new_buffer_with_data( + unsafe { mem::transmute(data.as_ptr()) }, + (data.len() * mem::size_of::<u32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache, + ) + }; + + let command_buffer = command_queue.new_command_buffer(); + + command_buffer.set_label("label"); + let block = block::ConcreteBlock::new(move |buffer: &metal::CommandBufferRef| { + println!("{}", buffer.label()); + }) + .copy(); + + command_buffer.add_completed_handler(&block); + + let encoder = command_buffer.new_compute_command_encoder(); + let library_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("examples/compute/shaders.metallib"); + + let library = device.new_library_with_file(library_path).unwrap(); + let kernel = library.get_function("sum", None).unwrap(); + + let pipeline_state_descriptor = ComputePipelineDescriptor::new(); + pipeline_state_descriptor.set_compute_function(Some(&kernel)); + + let pipeline_state = device + .new_compute_pipeline_state_with_function( + pipeline_state_descriptor.compute_function().unwrap(), + ) + .unwrap(); + + encoder.set_compute_pipeline_state(&pipeline_state); + encoder.set_buffer(0, Some(&buffer), 0); + encoder.set_buffer(1, Some(&sum), 0); + + let width = 16; + + let thread_group_count = MTLSize { + width, + height: 1, + depth: 1, + }; + + let thread_group_size = MTLSize { + width: (data.len() as u64 + width) / width, + height: 1, + depth: 1, + }; + + encoder.dispatch_thread_groups(thread_group_count, thread_group_size); + encoder.end_encoding(); + command_buffer.commit(); + command_buffer.wait_until_completed(); + + let ptr = sum.contents() as *mut u32; + + unsafe { + assert_eq!(465, *ptr); + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/compute/shaders.metal b/third_party/rust/metal/examples/compute/shaders.metal new file mode 100644 index 0000000000..51363a1d36 --- /dev/null +++ b/third_party/rust/metal/examples/compute/shaders.metal @@ -0,0 +1,10 @@ +#include <metal_stdlib> + +using namespace metal; + +kernel void sum(device uint *data [[ buffer(0) ]], + volatile device atomic_uint *sum [[ buffer(1) ]], + uint gid [[ thread_position_in_grid ]]) +{ + atomic_fetch_add_explicit(sum, data[gid], memory_order_relaxed); +} diff --git a/third_party/rust/metal/examples/compute/shaders.metallib b/third_party/rust/metal/examples/compute/shaders.metallib Binary files differnew file mode 100644 index 0000000000..af7cb17240 --- /dev/null +++ b/third_party/rust/metal/examples/compute/shaders.metallib diff --git a/third_party/rust/metal/examples/headless-render/README.md b/third_party/rust/metal/examples/headless-render/README.md new file mode 100644 index 0000000000..6bc434b44a --- /dev/null +++ b/third_party/rust/metal/examples/headless-render/README.md @@ -0,0 +1,11 @@ +## headless-render + +Renders the triangle from the [window example](../window) headlessly and then writes it to a PNG file. + +![Screenshot of the final render](./screenshot.png) + +## To Run + +``` +cargo run --example headless-render +``` diff --git a/third_party/rust/metal/examples/headless-render/main.rs b/third_party/rust/metal/examples/headless-render/main.rs new file mode 100644 index 0000000000..ed68da1a53 --- /dev/null +++ b/third_party/rust/metal/examples/headless-render/main.rs @@ -0,0 +1,159 @@ +use std::mem; +use std::path::PathBuf; + +use std::fs::File; +use std::io::BufWriter; + +use metal::{ + Buffer, Device, DeviceRef, LibraryRef, MTLClearColor, MTLLoadAction, MTLOrigin, MTLPixelFormat, + MTLPrimitiveType, MTLRegion, MTLResourceOptions, MTLSize, MTLStoreAction, RenderPassDescriptor, + RenderPassDescriptorRef, RenderPipelineDescriptor, RenderPipelineState, Texture, + TextureDescriptor, TextureRef, +}; +use png::ColorType; + +const VIEW_WIDTH: u64 = 512; +const VIEW_HEIGHT: u64 = 512; +const TOTAL_BYTES: usize = (VIEW_WIDTH * VIEW_HEIGHT * 4) as usize; + +const VERTEX_SHADER: &'static str = "triangle_vertex"; +const FRAGMENT_SHADER: &'static str = "triangle_fragment"; + +// [2 bytes position, 3 bytes color] * 3 +#[rustfmt::skip] +const VERTEX_ATTRIBS: [f32; 15] = [ + 0.0, 0.5, 1.0, 0.0, 0.0, + -0.5, -0.5, 0.0, 1.0, 0.0, + 0.5, -0.5, 0.0, 0.0, 1.0, +]; + +/// This example shows how to render headlessly by: +/// +/// 1. Rendering a triangle to an MtlDrawable +/// +/// 2. Waiting for the render to complete and the color texture to be synchronized with the CPU +/// by using a blit command encoder +/// +/// 3. Reading the texture bytes from the MtlTexture +/// +/// 4. Saving the texture to a PNG file +fn main() { + let device = Device::system_default().expect("No device found"); + + let texture = create_texture(&device); + + let library_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("examples/window/shaders.metallib"); + + let library = device.new_library_with_file(library_path).unwrap(); + + let pipeline_state = prepare_pipeline_state(&device, &library); + + let command_queue = device.new_command_queue(); + + let vertex_buffer = create_vertex_buffer(&device); + + let render_pass_descriptor = RenderPassDescriptor::new(); + initialize_color_attachment(&render_pass_descriptor, &texture); + + let command_buffer = command_queue.new_command_buffer(); + let rc_encoder = command_buffer.new_render_command_encoder(&render_pass_descriptor); + rc_encoder.set_render_pipeline_state(&pipeline_state); + rc_encoder.set_vertex_buffer(0, Some(&vertex_buffer), 0); + rc_encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 3); + rc_encoder.end_encoding(); + + render_pass_descriptor + .color_attachments() + .object_at(0) + .unwrap() + .set_load_action(MTLLoadAction::DontCare); + + let blit_encoder = command_buffer.new_blit_command_encoder(); + blit_encoder.synchronize_resource(&texture); + blit_encoder.end_encoding(); + + command_buffer.commit(); + + command_buffer.wait_until_completed(); + + save_image(&texture); +} + +fn save_image(texture: &TextureRef) { + let mut image = vec![0; TOTAL_BYTES]; + + texture.get_bytes( + image.as_mut_ptr() as *mut std::ffi::c_void, + VIEW_WIDTH * 4, + MTLRegion { + origin: MTLOrigin { x: 0, y: 0, z: 0 }, + size: MTLSize { + width: VIEW_WIDTH, + height: VIEW_HEIGHT, + depth: 1, + }, + }, + 0, + ); + + let out_file = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples/headless-render/out.png"); + let file = File::create(&out_file).unwrap(); + let ref mut w = BufWriter::new(file); + + let mut encoder = png::Encoder::new(w, VIEW_WIDTH as u32, VIEW_HEIGHT as u32); + encoder.set_color(ColorType::RGBA); + encoder.set_depth(png::BitDepth::Eight); + let mut writer = encoder.write_header().unwrap(); + + writer.write_image_data(&image).unwrap(); + + println!("Image saved to {:?}", out_file); +} + +fn create_texture(device: &Device) -> Texture { + let texture = TextureDescriptor::new(); + texture.set_width(VIEW_WIDTH); + texture.set_height(VIEW_HEIGHT); + texture.set_pixel_format(MTLPixelFormat::RGBA8Unorm); + + device.new_texture(&texture) +} + +fn prepare_pipeline_state(device: &DeviceRef, library: &LibraryRef) -> RenderPipelineState { + let vert = library.get_function(VERTEX_SHADER, None).unwrap(); + let frag = library.get_function(FRAGMENT_SHADER, None).unwrap(); + + let pipeline_state_descriptor = RenderPipelineDescriptor::new(); + + pipeline_state_descriptor.set_vertex_function(Some(&vert)); + pipeline_state_descriptor.set_fragment_function(Some(&frag)); + + pipeline_state_descriptor + .color_attachments() + .object_at(0) + .unwrap() + .set_pixel_format(MTLPixelFormat::RGBA8Unorm); + + device + .new_render_pipeline_state(&pipeline_state_descriptor) + .unwrap() +} + +fn create_vertex_buffer(device: &DeviceRef) -> Buffer { + device.new_buffer_with_data( + VERTEX_ATTRIBS.as_ptr() as *const _, + (VERTEX_ATTRIBS.len() * mem::size_of::<f32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache | MTLResourceOptions::StorageModeManaged, + ) +} + +fn initialize_color_attachment(descriptor: &RenderPassDescriptorRef, texture: &TextureRef) { + let color_attachment = descriptor.color_attachments().object_at(0).unwrap(); + + color_attachment.set_texture(Some(texture)); + color_attachment.set_load_action(MTLLoadAction::Clear); + color_attachment.set_clear_color(MTLClearColor::new(0.5, 0.2, 0.2, 1.0)); + color_attachment.set_store_action(MTLStoreAction::Store); +} diff --git a/third_party/rust/metal/examples/headless-render/screenshot.png b/third_party/rust/metal/examples/headless-render/screenshot.png Binary files differnew file mode 100644 index 0000000000..2af9c5895f --- /dev/null +++ b/third_party/rust/metal/examples/headless-render/screenshot.png diff --git a/third_party/rust/metal/examples/library/main.rs b/third_party/rust/metal/examples/library/main.rs new file mode 100644 index 0000000000..7223db89c1 --- /dev/null +++ b/third_party/rust/metal/examples/library/main.rs @@ -0,0 +1,17 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use metal::*; + +const PROGRAM: &'static str = ""; + +fn main() { + let device = Device::system_default().expect("no device found"); + + let options = CompileOptions::new(); + let _library = device.new_library_with_source(PROGRAM, &options); +} diff --git a/third_party/rust/metal/examples/reflection/main.rs b/third_party/rust/metal/examples/reflection/main.rs new file mode 100644 index 0000000000..41208d1845 --- /dev/null +++ b/third_party/rust/metal/examples/reflection/main.rs @@ -0,0 +1,83 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[macro_use] +extern crate objc; + +use metal::*; + +use cocoa::foundation::NSAutoreleasePool; + +const PROGRAM: &'static str = " + #include <metal_stdlib>\n\ + + using namespace metal;\n\ + + typedef struct {\n\ + float2 position;\n\ + float3 color;\n\ + } vertex_t;\n\ + + struct ColorInOut {\n\ + float4 position [[position]];\n\ + float4 color;\n\ + };\n\ + + vertex ColorInOut vs(device vertex_t* vertex_array [[ buffer(0) ]],\n\ + unsigned int vid [[ vertex_id ]])\n\ + {\n\ + ColorInOut out;\n\ + + out.position = float4(float2(vertex_array[vid].position), 0.0, 1.0);\n\ + out.color = float4(float3(vertex_array[vid].color), 1.0);\n\ + + return out;\n\ + }\n\ + + fragment float4 ps(ColorInOut in [[stage_in]])\n\ + {\n\ + return in.color;\n\ + };\n\ +"; + +fn main() { + let pool = unsafe { NSAutoreleasePool::new(cocoa::base::nil) }; + + let device = Device::system_default().expect("no device found"); + + let options = CompileOptions::new(); + let library = device.new_library_with_source(PROGRAM, &options).unwrap(); + let (vs, ps) = ( + library.get_function("vs", None).unwrap(), + library.get_function("ps", None).unwrap(), + ); + + let vertex_desc = VertexDescriptor::new(); + + let desc = RenderPipelineDescriptor::new(); + desc.set_vertex_function(Some(&vs)); + desc.set_fragment_function(Some(&ps)); + desc.set_vertex_descriptor(Some(vertex_desc)); + + println!("{:?}", desc); + + #[cfg(features = "private")] + let _reflection = unsafe { + RenderPipelineReflection::new( + desc.serialize_vertex_data(), + desc.serialize_fragment_data(), + vertex_desc.serialize_descriptor(), + &device, + 0x8, + 0x0, + ) + }; + + unsafe { + let () = msg_send![pool, release]; + } +} diff --git a/third_party/rust/metal/examples/window/README.md b/third_party/rust/metal/examples/window/README.md new file mode 100644 index 0000000000..62233be356 --- /dev/null +++ b/third_party/rust/metal/examples/window/README.md @@ -0,0 +1,11 @@ +## window + +Renders a spinning triangle to a [winit](https://github.com/rust-windowing/winit) window. + +![Screenshot of the final render](./screenshot.png) + +## To Run + +``` +cargo run --example window +``` diff --git a/third_party/rust/metal/examples/window/main.rs b/third_party/rust/metal/examples/window/main.rs new file mode 100644 index 0000000000..383933e3d3 --- /dev/null +++ b/third_party/rust/metal/examples/window/main.rs @@ -0,0 +1,178 @@ +// Copyright 2016 metal-rs developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +extern crate objc; + +use cocoa::{appkit::NSView, base::id as cocoa_id, foundation::NSRange}; + +use metal::*; +use objc::runtime::YES; +use std::mem; +use winit::platform::macos::WindowExtMacOS; + +use winit::{ + event::{Event, WindowEvent}, + event_loop::ControlFlow, +}; + +fn prepare_pipeline_state<'a>(device: &DeviceRef, library: &LibraryRef) -> RenderPipelineState { + let vert = library.get_function("triangle_vertex", None).unwrap(); + let frag = library.get_function("triangle_fragment", None).unwrap(); + + let pipeline_state_descriptor = RenderPipelineDescriptor::new(); + pipeline_state_descriptor.set_vertex_function(Some(&vert)); + pipeline_state_descriptor.set_fragment_function(Some(&frag)); + let attachment = pipeline_state_descriptor + .color_attachments() + .object_at(0) + .unwrap(); + attachment.set_pixel_format(MTLPixelFormat::BGRA8Unorm); + + attachment.set_blending_enabled(true); + attachment.set_rgb_blend_operation(metal::MTLBlendOperation::Add); + attachment.set_alpha_blend_operation(metal::MTLBlendOperation::Add); + attachment.set_source_rgb_blend_factor(metal::MTLBlendFactor::SourceAlpha); + attachment.set_source_alpha_blend_factor(metal::MTLBlendFactor::SourceAlpha); + attachment.set_destination_rgb_blend_factor(metal::MTLBlendFactor::OneMinusSourceAlpha); + attachment.set_destination_alpha_blend_factor(metal::MTLBlendFactor::OneMinusSourceAlpha); + + device + .new_render_pipeline_state(&pipeline_state_descriptor) + .unwrap() +} + +fn prepare_render_pass_descriptor(descriptor: &RenderPassDescriptorRef, texture: &TextureRef) { + //descriptor.color_attachments().set_object_at(0, MTLRenderPassColorAttachmentDescriptor::alloc()); + //let color_attachment: MTLRenderPassColorAttachmentDescriptor = unsafe { msg_send![descriptor.color_attachments().0, _descriptorAtIndex:0] };//descriptor.color_attachments().object_at(0); + let color_attachment = descriptor.color_attachments().object_at(0).unwrap(); + + color_attachment.set_texture(Some(texture)); + color_attachment.set_load_action(MTLLoadAction::Clear); + color_attachment.set_clear_color(MTLClearColor::new(0.5, 0.2, 0.2, 1.0)); + color_attachment.set_store_action(MTLStoreAction::Store); +} + +fn main() { + let events_loop = winit::event_loop::EventLoop::new(); + let size = winit::dpi::LogicalSize::new(800, 600); + + let window = winit::window::WindowBuilder::new() + .with_inner_size(size) + .with_title("Metal Window Example".to_string()) + .build(&events_loop) + .unwrap(); + + let device = Device::system_default().expect("no device found"); + + let layer = CoreAnimationLayer::new(); + layer.set_device(&device); + layer.set_pixel_format(MTLPixelFormat::BGRA8Unorm); + layer.set_presents_with_transaction(false); + + unsafe { + let view = window.ns_view() as cocoa_id; + view.setWantsLayer(YES); + view.setLayer(mem::transmute(layer.as_ref())); + } + + let draw_size = window.inner_size(); + layer.set_drawable_size(CGSize::new(draw_size.width as f64, draw_size.height as f64)); + + let library_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("examples/window/shaders.metallib"); + + let library = device.new_library_with_file(library_path).unwrap(); + let pipeline_state = prepare_pipeline_state(&device, &library); + let command_queue = device.new_command_queue(); + //let nc: () = msg_send![command_queue.0, setExecutionEnabled:true]; + + let vbuf = { + let vertex_data = [ + 0.0f32, 0.5, 1.0, 0.0, 0.0, -0.5, -0.5, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 0.0, 1.0, + ]; + + device.new_buffer_with_data( + vertex_data.as_ptr() as *const _, + (vertex_data.len() * mem::size_of::<f32>()) as u64, + MTLResourceOptions::CPUCacheModeDefaultCache | MTLResourceOptions::StorageModeManaged, + ) + }; + + let mut r = 0.0f32; + + events_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Poll; + + match event { + Event::WindowEvent { event, .. } => match event { + WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, + WindowEvent::Resized(size) => { + layer.set_drawable_size(CGSize::new(size.width as f64, size.height as f64)); + } + _ => (), + }, + Event::MainEventsCleared => { + window.request_redraw(); + } + Event::RedrawRequested(_) => { + let p = vbuf.contents(); + let vertex_data = [ + 0.0f32, + 0.5, + 1.0, + 0.0, + 0.0, + -0.5 + (r.cos() / 2. + 0.5), + -0.5, + 0.0, + 1.0, + 0.0, + 0.5 - (r.cos() / 2. + 0.5), + -0.5, + 0.0, + 0.0, + 1.0, + ]; + + unsafe { + std::ptr::copy( + vertex_data.as_ptr(), + p as *mut f32, + (vertex_data.len() * mem::size_of::<f32>()) as usize, + ); + } + + vbuf.did_modify_range(NSRange::new( + 0 as u64, + (vertex_data.len() * mem::size_of::<f32>()) as u64, + )); + + let drawable = match layer.next_drawable() { + Some(drawable) => drawable, + None => return, + }; + + let render_pass_descriptor = RenderPassDescriptor::new(); + + prepare_render_pass_descriptor(&render_pass_descriptor, drawable.texture()); + + let command_buffer = command_queue.new_command_buffer(); + let encoder = command_buffer.new_render_command_encoder(&render_pass_descriptor); + encoder.set_render_pipeline_state(&pipeline_state); + encoder.set_vertex_buffer(0, Some(&vbuf), 0); + encoder.draw_primitives(MTLPrimitiveType::Triangle, 0, 3); + encoder.end_encoding(); + + command_buffer.present_drawable(&drawable); + command_buffer.commit(); + + r += 0.01f32; + } + _ => {} + } + }); +} diff --git a/third_party/rust/metal/examples/window/screenshot.png b/third_party/rust/metal/examples/window/screenshot.png Binary files differnew file mode 100644 index 0000000000..9f5eba8ccf --- /dev/null +++ b/third_party/rust/metal/examples/window/screenshot.png diff --git a/third_party/rust/metal/examples/window/shaders.metal b/third_party/rust/metal/examples/window/shaders.metal new file mode 100644 index 0000000000..3defda15f0 --- /dev/null +++ b/third_party/rust/metal/examples/window/shaders.metal @@ -0,0 +1,32 @@ +#include <metal_stdlib> + +using namespace metal; + +typedef struct { + packed_float2 position; + packed_float3 color; +} vertex_t; + +struct ColorInOut { + float4 position [[position]]; + float4 color; +}; + +// vertex shader function +vertex ColorInOut triangle_vertex(const device vertex_t* vertex_array [[ buffer(0) ]], + unsigned int vid [[ vertex_id ]]) +{ + ColorInOut out; + + auto device const &v = vertex_array[vid]; + out.position = float4(v.position.x, v.position.y, 0.0, 1.0); + out.color = float4(v.color.x, v.color.y, v.color.z, 0.2); + + return out; +} + +// fragment shader function +fragment float4 triangle_fragment(ColorInOut in [[stage_in]]) +{ + return in.color; +}; diff --git a/third_party/rust/metal/examples/window/shaders.metallib b/third_party/rust/metal/examples/window/shaders.metallib Binary files differnew file mode 100644 index 0000000000..a182b718fa --- /dev/null +++ b/third_party/rust/metal/examples/window/shaders.metallib diff --git a/third_party/rust/metal/src/argument.rs b/third_party/rust/metal/src/argument.rs new file mode 100644 index 0000000000..4eca3c1090 --- /dev/null +++ b/third_party/rust/metal/src/argument.rs @@ -0,0 +1,324 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use crate::{Array, MTLTextureType}; + +use cocoa_foundation::foundation::NSUInteger; +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLDataType { + None = 0, + + Struct = 1, + Array = 2, + + Float = 3, + Float2 = 4, + Float3 = 5, + Float4 = 6, + + Float2x2 = 7, + Float2x3 = 8, + Float2x4 = 9, + + Float3x2 = 10, + Float3x3 = 11, + Float3x4 = 12, + + Float4x2 = 13, + Float4x3 = 14, + Float4x4 = 15, + + Half = 16, + Half2 = 17, + Half3 = 18, + Half4 = 19, + + Half2x2 = 20, + Half2x3 = 21, + Half2x4 = 22, + + Half3x2 = 23, + Half3x3 = 24, + Half3x4 = 25, + + Half4x2 = 26, + Half4x3 = 27, + Half4x4 = 28, + + Int = 29, + Int2 = 30, + Int3 = 31, + Int4 = 32, + + UInt = 33, + UInt2 = 34, + UInt3 = 35, + UInt4 = 36, + + Short = 37, + Short2 = 38, + Short3 = 39, + Short4 = 40, + + UShort = 41, + UShort2 = 42, + UShort3 = 43, + UShort4 = 44, + + Char = 45, + Char2 = 46, + Char3 = 47, + Char4 = 48, + + UChar = 49, + UChar2 = 50, + UChar3 = 51, + UChar4 = 52, + + Bool = 53, + Bool2 = 54, + Bool3 = 55, + Bool4 = 56, + + Texture = 58, + Sampler = 59, + Pointer = 60, + R8Unorm = 62, + R8Snorm = 63, + R16Unorm = 64, + R16Snorm = 65, + RG8Unorm = 66, + RG8Snorm = 67, + RG16Unorm = 68, + RG16Snorm = 69, + RGBA8Unorm = 70, + RGBA8Unorm_sRGB = 71, + RGBA8Snorm = 72, + RGBA16Unorm = 73, + RGBA16Snorm = 74, + RGB10A2Unorm = 75, + RG11B10Float = 76, + RGB9E5Float = 77, +} + +#[repr(u32)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLArgumentType { + Buffer = 0, + ThreadgroupMemory = 1, + Texture = 2, + Sampler = 3, + ImageblockData = 16, + Imageblock = 17, +} + +#[repr(u32)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLArgumentAccess { + ReadOnly = 0, + ReadWrite = 1, + WriteOnly = 2, +} + +pub enum MTLStructMember {} + +foreign_obj_type! { + type CType = MTLStructMember; + pub struct StructMember; + pub struct StructMemberRef; +} + +impl StructMemberRef { + pub fn name(&self) -> &str { + unsafe { + let name = msg_send![self, name]; + crate::nsstring_as_str(name) + } + } + + pub fn offset(&self) -> NSUInteger { + unsafe { msg_send![self, offset] } + } + + pub fn data_type(&self) -> MTLDataType { + unsafe { msg_send![self, dataType] } + } + + pub fn struct_type(&self) -> MTLStructType { + unsafe { msg_send![self, structType] } + } + + pub fn array_type(&self) -> MTLArrayType { + unsafe { msg_send![self, arrayType] } + } +} + +pub enum MTLStructType {} + +foreign_obj_type! { + type CType = MTLStructType; + pub struct StructType; + pub struct StructTypeRef; +} + +impl StructTypeRef { + pub fn members(&self) -> &Array<StructMember> { + unsafe { msg_send![self, members] } + } + + pub fn member_from_name(&self, name: &str) -> Option<&StructMemberRef> { + let nsname = crate::nsstring_from_str(name); + + unsafe { msg_send![self, memberByName: nsname] } + } +} + +pub enum MTLArrayType {} + +foreign_obj_type! { + type CType = MTLArrayType; + pub struct ArrayType; + pub struct ArrayTypeRef; +} + +impl ArrayTypeRef { + pub fn array_length(&self) -> NSUInteger { + unsafe { msg_send![self, arrayLength] } + } + + pub fn stride(&self) -> NSUInteger { + unsafe { msg_send![self, stride] } + } + + pub fn element_type(&self) -> MTLDataType { + unsafe { msg_send![self, elementType] } + } + + pub fn element_struct_type(&self) -> MTLStructType { + unsafe { msg_send![self, elementStructType] } + } + + pub fn element_array_type(&self) -> MTLArrayType { + unsafe { msg_send![self, elementArrayType] } + } +} + +pub enum MTLArgument {} + +foreign_obj_type! { + type CType = MTLArgument; + pub struct Argument; + pub struct ArgumentRef; +} + +impl ArgumentRef { + pub fn name(&self) -> &str { + unsafe { + let name = msg_send![self, name]; + crate::nsstring_as_str(name) + } + } + + pub fn type_(&self) -> MTLArgumentType { + unsafe { msg_send![self, type] } + } + + pub fn access(&self) -> MTLArgumentAccess { + unsafe { msg_send![self, access] } + } + + pub fn index(&self) -> NSUInteger { + unsafe { msg_send![self, index] } + } + + pub fn is_active(&self) -> bool { + unsafe { + match msg_send![self, isActive] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn buffer_alignment(&self) -> NSUInteger { + unsafe { msg_send![self, bufferAlignment] } + } + + pub fn buffer_data_size(&self) -> NSUInteger { + unsafe { msg_send![self, bufferDataSize] } + } + + pub fn buffer_data_type(&self) -> MTLDataType { + unsafe { msg_send![self, bufferDataType] } + } + + pub fn buffer_struct_type(&self) -> &StructTypeRef { + unsafe { msg_send![self, bufferStructType] } + } + + pub fn threadgroup_memory_alignment(&self) -> NSUInteger { + unsafe { msg_send![self, threadgroupMemoryAlignment] } + } + + pub fn threadgroup_memory_data_size(&self) -> NSUInteger { + unsafe { msg_send![self, threadgroupMemoryDataSize] } + } + + pub fn texture_type(&self) -> MTLTextureType { + unsafe { msg_send![self, textureType] } + } + + pub fn texture_data_type(&self) -> MTLDataType { + unsafe { msg_send![self, textureDataType] } + } +} + +pub enum MTLArgumentDescriptor {} + +foreign_obj_type! { + type CType = MTLArgumentDescriptor; + pub struct ArgumentDescriptor; + pub struct ArgumentDescriptorRef; +} + +impl ArgumentDescriptor { + pub fn new<'a>() -> &'a ArgumentDescriptorRef { + unsafe { + let class = class!(MTLArgumentDescriptor); + msg_send![class, argumentDescriptor] + } + } +} + +impl ArgumentDescriptorRef { + pub fn set_data_type(&self, ty: MTLDataType) { + unsafe { msg_send![self, setDataType: ty] } + } + + pub fn set_index(&self, index: NSUInteger) { + unsafe { msg_send![self, setIndex: index] } + } + + pub fn set_access(&self, access: MTLArgumentAccess) { + unsafe { msg_send![self, setAccess: access] } + } + + pub fn set_array_length(&self, length: NSUInteger) { + unsafe { msg_send![self, setArrayLength: length] } + } + + pub fn set_texture_type(&self, ty: MTLTextureType) { + unsafe { msg_send![self, setTextureType: ty] } + } +} diff --git a/third_party/rust/metal/src/buffer.rs b/third_party/rust/metal/src/buffer.rs new file mode 100644 index 0000000000..885549f6f8 --- /dev/null +++ b/third_party/rust/metal/src/buffer.rs @@ -0,0 +1,55 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSRange; + +pub enum MTLBuffer {} + +foreign_obj_type! { + type CType = MTLBuffer; + pub struct Buffer; + pub struct BufferRef; + type ParentType = ResourceRef; +} + +impl BufferRef { + pub fn length(&self) -> u64 { + unsafe { msg_send![self, length] } + } + + pub fn contents(&self) -> *mut std::ffi::c_void { + unsafe { msg_send![self, contents] } + } + + pub fn did_modify_range(&self, range: NSRange) { + unsafe { msg_send![self, didModifyRange: range] } + } + + pub fn new_texture_from_contents( + &self, + descriptor: &TextureDescriptorRef, + offset: u64, + stride: u64, + ) -> Texture { + unsafe { + msg_send![self, + newTextureWithDescriptor:descriptor + offset:offset + bytesPerRow:stride + ] + } + } + + pub fn add_debug_marker(&self, name: &str, range: NSRange) { + unsafe { + let name = crate::nsstring_from_str(name); + msg_send![self, addDebugMarker:name range:range] + } + } +} diff --git a/third_party/rust/metal/src/capturedescriptor.rs b/third_party/rust/metal/src/capturedescriptor.rs new file mode 100644 index 0000000000..ac36a92504 --- /dev/null +++ b/third_party/rust/metal/src/capturedescriptor.rs @@ -0,0 +1,79 @@ +// Copyright 2020 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use std::path::Path; + +/// https://developer.apple.com/documentation/metal/mtlcapturedestination?language=objc +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLCaptureDestination { + DeveloperTools = 1, + GpuTraceDocument = 2, +} + +/// https://developer.apple.com/documentation/metal/mtlcapturedescriptor +pub enum MTLCaptureDescriptor {} + +foreign_obj_type! { + type CType = MTLCaptureDescriptor; + pub struct CaptureDescriptor; + pub struct CaptureDescriptorRef; +} + +impl CaptureDescriptor { + pub fn new() -> CaptureDescriptor { + unsafe { + let class = class!(MTLCaptureDescriptor); + msg_send![class, new] + } + } +} + +impl CaptureDescriptorRef { + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor/3237248-captureobject + pub fn set_capture_device(&self, device: &DeviceRef) { + unsafe { msg_send![self, setCaptureObject: device] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor/3237248-captureobject + pub fn set_capture_scope(&self, scope: &CaptureScopeRef) { + unsafe { msg_send![self, setCaptureObject: scope] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor/3237248-captureobject + pub fn set_capture_command_queue(&self, command_queue: &CommandQueueRef) { + unsafe { msg_send![self, setCaptureObject: command_queue] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor/3237250-outputurl + pub fn output_url(&self) -> &Path { + let output_url = unsafe { msg_send![self, outputURL] }; + let output_url = nsstring_as_str(output_url); + + Path::new(output_url) + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor/3237250-outputurl + pub fn set_output_url<P: AsRef<Path>>(&self, output_url: P) { + let output_url = nsstring_from_str(output_url.as_ref().to_str().unwrap()); + + unsafe { msg_send![self, setOutputURL: output_url] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor?language=objc + pub fn destination(&self) -> MTLCaptureDestination { + unsafe { msg_send![self, destination] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturedescriptor?language=objc + pub fn set_destination(&self, destination: MTLCaptureDestination) { + unsafe { msg_send![self, setDestination: destination] } + } +} diff --git a/third_party/rust/metal/src/capturemanager.rs b/third_party/rust/metal/src/capturemanager.rs new file mode 100644 index 0000000000..95180c4239 --- /dev/null +++ b/third_party/rust/metal/src/capturemanager.rs @@ -0,0 +1,107 @@ +// Copyright 2018 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; +use std::ffi::CStr; + +pub enum MTLCaptureScope {} + +foreign_obj_type! { + type CType = MTLCaptureScope; + pub struct CaptureScope; + pub struct CaptureScopeRef; +} + +impl CaptureScopeRef { + pub fn begin_scope(&self) { + unsafe { msg_send![self, beginScope] } + } + + pub fn end_scope(&self) { + unsafe { msg_send![self, endScope] } + } + + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } +} + +pub enum MTLCaptureManager {} + +foreign_obj_type! { + type CType = MTLCaptureManager; + pub struct CaptureManager; + pub struct CaptureManagerRef; +} + +impl CaptureManager { + pub fn shared<'a>() -> &'a CaptureManagerRef { + unsafe { + let class = class!(MTLCaptureManager); + msg_send![class, sharedCaptureManager] + } + } +} + +impl CaptureManagerRef { + pub fn new_capture_scope_with_device(&self, device: &DeviceRef) -> CaptureScope { + unsafe { msg_send![self, newCaptureScopeWithDevice: device] } + } + + pub fn new_capture_scope_with_command_queue( + &self, + command_queue: &CommandQueueRef, + ) -> CaptureScope { + unsafe { msg_send![self, newCaptureScopeWithCommandQueue: command_queue] } + } + + pub fn default_capture_scope(&self) -> Option<&CaptureScopeRef> { + unsafe { msg_send![self, defaultCaptureScope] } + } + + pub fn set_default_capture_scope(&self, scope: &CaptureScopeRef) { + unsafe { msg_send![self, setDefaultCaptureScope: scope] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturemanager/3237259-startcapture + pub fn start_capture(&self, descriptor: &CaptureDescriptorRef) -> Result<(), String> { + unsafe { + try_objc! { err => + msg_send![self, startCaptureWithDescriptor: descriptor + error: &mut err] + } + } + } + + pub fn start_capture_with_device(&self, device: &DeviceRef) { + unsafe { msg_send![self, startCaptureWithDevice: device] } + } + + pub fn start_capture_with_command_queue(&self, command_queue: &CommandQueueRef) { + unsafe { msg_send![self, startCaptureWithCommandQueue: command_queue] } + } + + pub fn start_capture_with_scope(&self, scope: &CaptureScopeRef) { + unsafe { msg_send![self, startCaptureWithScope: scope] } + } + + pub fn stop_capture(&self) { + unsafe { msg_send![self, stopCapture] } + } + + pub fn is_capturing(&self) -> bool { + unsafe { msg_send![self, isCapturing] } + } + + /// https://developer.apple.com/documentation/metal/mtlcapturemanager/3237260-supportsdestination?language=objc + pub fn supports_destination(&self, destination: MTLCaptureDestination) -> bool { + unsafe { msg_send![self, supportsDestination: destination] } + } +} diff --git a/third_party/rust/metal/src/commandbuffer.rs b/third_party/rust/metal/src/commandbuffer.rs new file mode 100644 index 0000000000..a21c5f1779 --- /dev/null +++ b/third_party/rust/metal/src/commandbuffer.rs @@ -0,0 +1,129 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use block::Block; + +#[repr(u32)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLCommandBufferStatus { + NotEnqueued = 0, + Enqueued = 1, + Committed = 2, + Scheduled = 3, + Completed = 4, + Error = 5, +} + +#[repr(u32)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLCommandBufferError { + None = 0, + Internal = 1, + Timeout = 2, + PageFault = 3, + Blacklisted = 4, + NotPermitted = 7, + OutOfMemory = 8, + InvalidResource = 9, + Memoryless = 10, + DeviceRemoved = 11, +} + +#[repr(u32)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLDispatchType { + Serial = 0, + Concurrent = 1, +} + +type CommandBufferHandler<'a> = Block<(&'a CommandBufferRef,), ()>; + +pub enum MTLCommandBuffer {} + +foreign_obj_type! { + type CType = MTLCommandBuffer; + pub struct CommandBuffer; + pub struct CommandBufferRef; +} + +impl CommandBufferRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn enqueue(&self) { + unsafe { msg_send![self, enqueue] } + } + + pub fn commit(&self) { + unsafe { msg_send![self, commit] } + } + + pub fn status(&self) -> MTLCommandBufferStatus { + unsafe { msg_send![self, status] } + } + + pub fn present_drawable(&self, drawable: &DrawableRef) { + unsafe { msg_send![self, presentDrawable: drawable] } + } + + pub fn wait_until_completed(&self) { + unsafe { msg_send![self, waitUntilCompleted] } + } + + pub fn wait_until_scheduled(&self) { + unsafe { msg_send![self, waitUntilScheduled] } + } + + pub fn add_completed_handler(&self, block: &CommandBufferHandler) { + unsafe { msg_send![self, addCompletedHandler: block] } + } + + pub fn new_blit_command_encoder(&self) -> &BlitCommandEncoderRef { + unsafe { msg_send![self, blitCommandEncoder] } + } + + pub fn new_compute_command_encoder(&self) -> &ComputeCommandEncoderRef { + unsafe { msg_send![self, computeCommandEncoder] } + } + + pub fn new_render_command_encoder( + &self, + descriptor: &RenderPassDescriptorRef, + ) -> &RenderCommandEncoderRef { + unsafe { msg_send![self, renderCommandEncoderWithDescriptor: descriptor] } + } + + pub fn new_parallel_render_command_encoder( + &self, + descriptor: &RenderPassDescriptorRef, + ) -> &ParallelRenderCommandEncoderRef { + unsafe { msg_send![self, parallelRenderCommandEncoderWithDescriptor: descriptor] } + } + + pub fn compute_command_encoder_with_dispatch_type( + &self, + ty: MTLDispatchType, + ) -> &ComputeCommandEncoderRef { + unsafe { msg_send![self, computeCommandEncoderWithDispatchType: ty] } + } +} diff --git a/third_party/rust/metal/src/commandqueue.rs b/third_party/rust/metal/src/commandqueue.rs new file mode 100644 index 0000000000..470d8dbe93 --- /dev/null +++ b/third_party/rust/metal/src/commandqueue.rs @@ -0,0 +1,44 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +pub enum MTLCommandQueue {} + +foreign_obj_type! { + type CType = MTLCommandQueue; + pub struct CommandQueue; + pub struct CommandQueueRef; +} + +impl CommandQueueRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn new_command_buffer(&self) -> &CommandBufferRef { + unsafe { msg_send![self, commandBuffer] } + } + + pub fn new_command_buffer_with_unretained_references(&self) -> &CommandBufferRef { + unsafe { msg_send![self, commandBufferWithUnretainedReferences] } + } + + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } +} diff --git a/third_party/rust/metal/src/constants.rs b/third_party/rust/metal/src/constants.rs new file mode 100644 index 0000000000..b6765a04cd --- /dev/null +++ b/third_party/rust/metal/src/constants.rs @@ -0,0 +1,137 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum MTLPixelFormat { + Invalid = 0, + A8Unorm = 1, + R8Unorm = 10, + R8Unorm_sRGB = 11, + R8Snorm = 12, + R8Uint = 13, + R8Sint = 14, + R16Unorm = 20, + R16Snorm = 22, + R16Uint = 23, + R16Sint = 24, + R16Float = 25, + RG8Unorm = 30, + RG8Unorm_sRGB = 31, + RG8Snorm = 32, + RG8Uint = 33, + RG8Sint = 34, + B5G6R5Unorm = 40, + A1BGR5Unorm = 41, + ABGR4Unorm = 42, + BGR5A1Unorm = 43, + R32Uint = 53, + R32Sint = 54, + R32Float = 55, + RG16Unorm = 60, + RG16Snorm = 62, + RG16Uint = 63, + RG16Sint = 64, + RG16Float = 65, + RGBA8Unorm = 70, + RGBA8Unorm_sRGB = 71, + RGBA8Snorm = 72, + RGBA8Uint = 73, + RGBA8Sint = 74, + BGRA8Unorm = 80, + BGRA8Unorm_sRGB = 81, + RGB10A2Unorm = 90, + RGB10A2Uint = 91, + RG11B10Float = 92, + RGB9E5Float = 93, + BGR10A2Unorm = 94, + RG32Uint = 103, + RG32Sint = 104, + RG32Float = 105, + RGBA16Unorm = 110, + RGBA16Snorm = 112, + RGBA16Uint = 113, + RGBA16Sint = 114, + RGBA16Float = 115, + RGBA32Uint = 123, + RGBA32Sint = 124, + RGBA32Float = 125, + BC1_RGBA = 130, + BC1_RGBA_sRGB = 131, + BC2_RGBA = 132, + BC2_RGBA_sRGB = 133, + BC3_RGBA = 134, + BC3_RGBA_sRGB = 135, + BC4_RUnorm = 140, + BC4_RSnorm = 141, + BC5_RGUnorm = 142, + BC5_RGSnorm = 143, + BC6H_RGBFloat = 150, + BC6H_RGBUfloat = 151, + BC7_RGBAUnorm = 152, + BC7_RGBAUnorm_sRGB = 153, + PVRTC_RGB_2BPP = 160, + PVRTC_RGB_2BPP_sRGB = 161, + PVRTC_RGB_4BPP = 162, + PVRTC_RGB_4BPP_sRGB = 163, + PVRTC_RGBA_2BPP = 164, + PVRTC_RGBA_2BPP_sRGB = 165, + PVRTC_RGBA_4BPP = 166, + PVRTC_RGBA_4BPP_sRGB = 167, + EAC_R11Unorm = 170, + EAC_R11Snorm = 172, + EAC_RG11Unorm = 174, + EAC_RG11Snorm = 176, + EAC_RGBA8 = 178, + EAC_RGBA8_sRGB = 179, + ETC2_RGB8 = 180, + ETC2_RGB8_sRGB = 181, + ETC2_RGB8A1 = 182, + ETC2_RGB8A1_sRGB = 183, + ASTC_4x4_sRGB = 186, + ASTC_5x4_sRGB = 187, + ASTC_5x5_sRGB = 188, + ASTC_6x5_sRGB = 189, + ASTC_6x6_sRGB = 190, + ASTC_8x5_sRGB = 192, + ASTC_8x6_sRGB = 193, + ASTC_8x8_sRGB = 194, + ASTC_10x5_sRGB = 195, + ASTC_10x6_sRGB = 196, + ASTC_10x8_sRGB = 197, + ASTC_10x10_sRGB = 198, + ASTC_12x10_sRGB = 199, + ASTC_12x12_sRGB = 200, + ASTC_4x4_LDR = 204, + ASTC_5x4_LDR = 205, + ASTC_5x5_LDR = 206, + ASTC_6x5_LDR = 207, + ASTC_6x6_LDR = 208, + ASTC_8x5_LDR = 210, + ASTC_8x6_LDR = 211, + ASTC_8x8_LDR = 212, + ASTC_10x5_LDR = 213, + ASTC_10x6_LDR = 214, + ASTC_10x8_LDR = 215, + ASTC_10x10_LDR = 216, + ASTC_12x10_LDR = 217, + ASTC_12x12_LDR = 218, + GBGR422 = 240, + BGRG422 = 241, + Depth16Unorm = 250, + Depth32Float = 252, + Stencil8 = 253, + Depth24Unorm_Stencil8 = 255, + Depth32Float_Stencil8 = 260, + X32_Stencil8 = 261, + X24_Stencil8 = 262, + BGRA10_XR = 552, + BGRA10_XR_SRGB = 553, + BGR10_XR = 554, + BGR10_XR_SRGB = 555, +} diff --git a/third_party/rust/metal/src/depthstencil.rs b/third_party/rust/metal/src/depthstencil.rs new file mode 100644 index 0000000000..e00e68a9cd --- /dev/null +++ b/third_party/rust/metal/src/depthstencil.rs @@ -0,0 +1,166 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLCompareFunction { + Never = 0, + Less = 1, + Equal = 2, + LessEqual = 3, + Greater = 4, + NotEqual = 5, + GreaterEqual = 6, + Always = 7, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLStencilOperation { + Keep = 0, + Zero = 1, + Replace = 2, + IncrementClamp = 3, + DecrementClamp = 4, + Invert = 5, + IncrementWrap = 6, + DecrementWrap = 7, +} + +pub enum MTLStencilDescriptor {} + +foreign_obj_type! { + type CType = MTLStencilDescriptor; + pub struct StencilDescriptor; + pub struct StencilDescriptorRef; +} + +impl StencilDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLStencilDescriptor); + msg_send![class, new] + } + } +} + +impl StencilDescriptorRef { + pub fn stencil_compare_function(&self) -> MTLCompareFunction { + unsafe { msg_send![self, stencilCompareFunction] } + } + + pub fn set_stencil_compare_function(&self, func: MTLCompareFunction) { + unsafe { msg_send![self, setStencilCompareFunction: func] } + } + + pub fn stencil_failure_operation(&self) -> MTLStencilOperation { + unsafe { msg_send![self, stencilFailureOperation] } + } + + pub fn set_stencil_failure_operation(&self, operation: MTLStencilOperation) { + unsafe { msg_send![self, setStencilFailureOperation: operation] } + } + + pub fn depth_failure_operation(&self) -> MTLStencilOperation { + unsafe { msg_send![self, depthFailureOperation] } + } + + pub fn set_depth_failure_operation(&self, operation: MTLStencilOperation) { + unsafe { msg_send![self, setDepthFailureOperation: operation] } + } + + pub fn depth_stencil_pass_operation(&self) -> MTLStencilOperation { + unsafe { msg_send![self, depthStencilPassOperation] } + } + + pub fn set_depth_stencil_pass_operation(&self, operation: MTLStencilOperation) { + unsafe { msg_send![self, setDepthStencilPassOperation: operation] } + } + + pub fn read_mask(&self) -> u32 { + unsafe { msg_send![self, readMask] } + } + + pub fn set_read_mask(&self, mask: u32) { + unsafe { msg_send![self, setReadMask: mask] } + } + + pub fn write_mask(&self) -> u32 { + unsafe { msg_send![self, writeMask] } + } + + pub fn set_write_mask(&self, mask: u32) { + unsafe { msg_send![self, setWriteMask: mask] } + } +} + +pub enum MTLDepthStencilDescriptor {} + +foreign_obj_type! { + type CType = MTLDepthStencilDescriptor; + pub struct DepthStencilDescriptor; + pub struct DepthStencilDescriptorRef; +} + +impl DepthStencilDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLDepthStencilDescriptor); + msg_send![class, new] + } + } +} + +impl DepthStencilDescriptorRef { + pub fn depth_compare_function(&self) -> MTLCompareFunction { + unsafe { msg_send![self, depthCompareFunction] } + } + + pub fn set_depth_compare_function(&self, func: MTLCompareFunction) { + unsafe { msg_send![self, setDepthCompareFunction: func] } + } + + pub fn depth_write_enabled(&self) -> bool { + unsafe { + match msg_send![self, isDepthWriteEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_depth_write_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setDepthWriteEnabled: enabled] } + } + + pub fn front_face_stencil(&self) -> Option<&StencilDescriptorRef> { + unsafe { msg_send![self, frontFaceStencil] } + } + + pub fn set_front_face_stencil(&self, descriptor: Option<&StencilDescriptorRef>) { + unsafe { msg_send![self, setFrontFaceStencil: descriptor] } + } + + pub fn back_face_stencil(&self) -> Option<&StencilDescriptorRef> { + unsafe { msg_send![self, backFaceStencil] } + } + + pub fn set_back_face_stencil(&self, descriptor: Option<&StencilDescriptorRef>) { + unsafe { msg_send![self, setBackFaceStencil: descriptor] } + } +} + +pub enum MTLDepthStencilState {} + +foreign_obj_type! { + type CType = MTLDepthStencilState; + pub struct DepthStencilState; + pub struct DepthStencilStateRef; +} diff --git a/third_party/rust/metal/src/device.rs b/third_party/rust/metal/src/device.rs new file mode 100644 index 0000000000..53326511a2 --- /dev/null +++ b/third_party/rust/metal/src/device.rs @@ -0,0 +1,1753 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use block::{Block, ConcreteBlock}; +use cocoa_foundation::base::id; +use cocoa_foundation::foundation::NSUInteger; +use foreign_types::ForeignType; +use objc::runtime::{Object, BOOL, NO, YES}; + +use super::*; + +use std::ffi::CStr; +use std::path::Path; +use std::ptr; + +#[allow(non_camel_case_types)] +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLFeatureSet { + iOS_GPUFamily1_v1 = 0, + iOS_GPUFamily2_v1 = 1, + iOS_GPUFamily1_v2 = 2, + iOS_GPUFamily2_v2 = 3, + iOS_GPUFamily3_v1 = 4, + iOS_GPUFamily1_v3 = 5, + iOS_GPUFamily2_v3 = 6, + iOS_GPUFamily3_v2 = 7, + iOS_GPUFamily1_v4 = 8, + iOS_GPUFamily2_v4 = 9, + iOS_GPUFamily3_v3 = 10, + iOS_GPUFamily4_v1 = 11, + iOS_GPUFamily1_v5 = 12, + iOS_GPUFamily2_v5 = 13, + iOS_GPUFamily3_v4 = 14, + iOS_GPUFamily4_v2 = 15, + iOS_GPUFamily5_v1 = 16, + + tvOS_GPUFamily1_v1 = 30000, + tvOS_GPUFamily1_v2 = 30001, + tvOS_GPUFamily1_v3 = 30002, + tvOS_GPUFamily2_v1 = 30003, + tvOS_GPUFamily1_v4 = 30004, + tvOS_GPUFamily2_v2 = 30005, + + macOS_GPUFamily1_v1 = 10000, + macOS_GPUFamily1_v2 = 10001, + //macOS_ReadWriteTextureTier2 = 10002, TODO: Uncomment when feature tables updated + macOS_GPUFamily1_v3 = 10003, + macOS_GPUFamily1_v4 = 10004, + macOS_GPUFamily2_v1 = 10005, +} + +bitflags! { + pub struct PixelFormatCapabilities: u32 { + const Filter = 1 << 0; + const Write = 1 << 1; + const Color = 1 << 2; + const Blend = 1 << 3; + const Msaa = 1 << 4; + const Resolve = 1 << 5; + } +} + +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +enum OS { + iOS, + tvOS, + macOS, +} + +const KB: u32 = 1024; +const MB: u32 = 1024 * KB; +const GB: u32 = 1024 * MB; + +impl MTLFeatureSet { + fn os(&self) -> OS { + let value = *self as u64; + if value < 10_000 { + OS::iOS + } else if value < 20_000 { + OS::macOS + } else if value >= 30_000 || value < 40_000 { + OS::tvOS + } else { + unreachable!() + } + } + + // returns the minor version on macos + fn os_version(&self) -> u32 { + use MTLFeatureSet::*; + match self { + iOS_GPUFamily1_v1 | iOS_GPUFamily2_v1 => 8, + iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v1 => 9, + iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v2 => 10, + iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v3 | iOS_GPUFamily4_v1 => 11, + iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 | iOS_GPUFamily3_v4 | iOS_GPUFamily4_v2 + | iOS_GPUFamily5_v1 => 12, + tvOS_GPUFamily1_v1 => 9, + tvOS_GPUFamily1_v2 => 10, + tvOS_GPUFamily1_v3 | tvOS_GPUFamily2_v1 => 11, + tvOS_GPUFamily1_v4 | tvOS_GPUFamily2_v2 => 12, + macOS_GPUFamily1_v1 => 11, + macOS_GPUFamily1_v2 => 12, + macOS_GPUFamily1_v3 => 13, + macOS_GPUFamily1_v4 | macOS_GPUFamily2_v1 => 14, + } + } + + fn gpu_family(&self) -> u32 { + use MTLFeatureSet::*; + match self { + iOS_GPUFamily1_v1 | iOS_GPUFamily1_v2 | iOS_GPUFamily1_v3 | iOS_GPUFamily1_v4 + | iOS_GPUFamily1_v5 | tvOS_GPUFamily1_v1 | tvOS_GPUFamily1_v2 | tvOS_GPUFamily1_v3 + | tvOS_GPUFamily1_v4 | macOS_GPUFamily1_v1 | macOS_GPUFamily1_v2 + | macOS_GPUFamily1_v3 | macOS_GPUFamily1_v4 => 1, + iOS_GPUFamily2_v1 | iOS_GPUFamily2_v2 | iOS_GPUFamily2_v3 | iOS_GPUFamily2_v4 + | iOS_GPUFamily2_v5 | tvOS_GPUFamily2_v1 | tvOS_GPUFamily2_v2 | macOS_GPUFamily2_v1 => { + 2 + } + iOS_GPUFamily3_v1 | iOS_GPUFamily3_v2 | iOS_GPUFamily3_v3 | iOS_GPUFamily3_v4 => 3, + iOS_GPUFamily4_v1 | iOS_GPUFamily4_v2 => 4, + iOS_GPUFamily5_v1 => 5, + } + } + + fn version(&self) -> u32 { + use MTLFeatureSet::*; + match self { + iOS_GPUFamily1_v1 | iOS_GPUFamily2_v1 | iOS_GPUFamily3_v1 | iOS_GPUFamily4_v1 + | iOS_GPUFamily5_v1 | macOS_GPUFamily1_v1 | macOS_GPUFamily2_v1 + | tvOS_GPUFamily1_v1 | tvOS_GPUFamily2_v1 => 1, + iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v2 | iOS_GPUFamily4_v2 + | macOS_GPUFamily1_v2 | tvOS_GPUFamily1_v2 | tvOS_GPUFamily2_v2 => 2, + iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v3 | macOS_GPUFamily1_v3 + | tvOS_GPUFamily1_v3 => 3, + iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v4 | tvOS_GPUFamily1_v4 + | macOS_GPUFamily1_v4 => 4, + iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 => 5, + } + } + + pub fn supports_metal_kit(&self) -> bool { + true + } + + pub fn supports_metal_performance_shaders(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 2, + OS::tvOS => true, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_programmable_blending(&self) -> bool { + self.os() != OS::macOS + } + + pub fn supports_pvrtc_pixel_formats(&self) -> bool { + self.os() != OS::macOS + } + + pub fn supports_eac_etc_pixel_formats(&self) -> bool { + self.os() != OS::macOS + } + + pub fn supports_astc_pixel_formats(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 2, + OS::tvOS => true, + OS::macOS => false, + } + } + + pub fn supports_linear_textures(&self) -> bool { + self.os() != OS::macOS || self.os_version() >= 13 + } + + pub fn supports_bc_pixel_formats(&self) -> bool { + self.os() == OS::macOS + } + + pub fn supports_msaa_depth_resolve(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => false, + } + } + + pub fn supports_counting_occlusion_query(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + } + } + + pub fn supports_base_vertex_instance_drawing(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + } + } + + pub fn supports_indirect_buffers(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + } + } + + pub fn supports_cube_map_texture_arrays(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 4, + OS::tvOS => false, + OS::macOS => true, + } + } + + pub fn supports_texture_barriers(&self) -> bool { + self.os() == OS::macOS + } + + pub fn supports_layered_rendering(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 5, + OS::tvOS => false, + OS::macOS => true, + } + } + + pub fn supports_tessellation(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_resource_heaps(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_memoryless_render_targets(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => false, + } + } + + pub fn supports_function_specialization(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_function_buffer_read_writes(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_function_texture_read_writes(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 4, + OS::tvOS => false, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_array_of_textures(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_array_of_samplers(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 11, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_stencil_texture_views(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_depth_16_pixel_format(&self) -> bool { + self.os() == OS::macOS && self.os_version() >= 12 + } + + pub fn supports_extended_range_pixel_formats(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => false, + } + } + + pub fn supports_wide_color_pixel_format(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 11, + OS::tvOS => self.os_version() >= 11, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_combined_msaa_store_and_resolve_action(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_deferred_store_action(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_msaa_blits(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => true, + } + } + + pub fn supports_srgb_writes(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 3 || (self.gpu_family() >= 2 && self.version() >= 3), + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.gpu_family() >= 2, + } + } + + pub fn supports_16_bit_unsigned_integer_coordinates(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_extract_insert_and_reverse_bits(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_simd_barrier(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_sampler_max_anisotropy(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_sampler_lod_clamp(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 10, + OS::tvOS => self.os_version() >= 10, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_border_color(&self) -> bool { + self.os() == OS::macOS && self.os_version() >= 12 + } + + pub fn supports_dual_source_blending(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 11, + OS::tvOS => self.os_version() >= 11, + OS::macOS => self.os_version() >= 12, + } + } + + pub fn supports_argument_buffers(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 11, + OS::tvOS => self.os_version() >= 11, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_programmable_sample_positions(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 11, + OS::tvOS => self.os_version() >= 11, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_uniform_type(&self) -> bool { + match self.os() { + OS::iOS => self.os_version() >= 11, + OS::tvOS => self.os_version() >= 11, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_imageblocks(&self) -> bool { + self.os() == OS::iOS && self.gpu_family() >= 4 + } + + pub fn supports_tile_shaders(&self) -> bool { + self.os() == OS::iOS && self.gpu_family() >= 4 + } + + pub fn supports_imageblock_sample_coverage_control(&self) -> bool { + self.os() == OS::iOS && self.gpu_family() >= 4 + } + + pub fn supports_threadgroup_sharing(&self) -> bool { + self.os() == OS::iOS && self.gpu_family() >= 4 + } + + pub fn supports_post_depth_coverage(&self) -> bool { + self.os() == OS::iOS && self.gpu_family() >= 4 + } + + pub fn supports_quad_scoped_permute_operations(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 4, + OS::tvOS => false, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_raster_order_groups(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 4, + OS::tvOS => false, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_non_uniform_threadgroup_size(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 4, + OS::tvOS => false, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_multiple_viewports(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 5, + OS::tvOS => false, + OS::macOS => self.os_version() >= 13, + } + } + + pub fn supports_device_notifications(&self) -> bool { + self.os() == OS::macOS && self.os_version() >= 13 + } + + pub fn supports_stencil_feedback(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 5, + OS::tvOS => false, + OS::macOS => self.gpu_family() >= 2, + } + } + + pub fn supports_stencil_resolve(&self) -> bool { + match self.os() { + OS::iOS => self.gpu_family() >= 5, + OS::tvOS => false, + OS::macOS => self.gpu_family() >= 2, + } + } + + pub fn max_vertex_attributes(&self) -> u32 { + 31 + } + + pub fn max_buffer_argument_entries(&self) -> u32 { + 31 + } + + pub fn max_texture_argument_entries(&self) -> u32 { + if self.os() == OS::macOS { + 128 + } else { + 31 + } + } + + pub fn max_sampler_state_argument_entries(&self) -> u32 { + 16 + } + + pub fn max_threadgroup_memory_argument_entries(&self) -> u32 { + 31 + } + + pub fn max_inlined_constant_data_buffers(&self) -> u32 { + if self.os() == OS::macOS { + 14 + } else { + 31 + } + } + + pub fn max_inline_constant_buffer_length(&self) -> u32 { + 4 * KB + } + + pub fn max_threads_per_threadgroup(&self) -> u32 { + if self.os() == OS::macOS || self.gpu_family() >= 4 { + 1024 + } else { + 512 + } + } + + pub fn max_total_threadgroup_memory_allocation(&self) -> u32 { + match (self.os(), self.gpu_family()) { + (OS::iOS, 5) => 64 * KB, + (OS::iOS, 4) => { + if self.os_version() >= 12 { + 64 * KB + } else { + 32 * KB + } + } + (OS::iOS, 3) => 16 * KB, + (OS::iOS, _) => 16 * KB - 32, + (OS::tvOS, 1) => 16 * KB - 32, + (OS::tvOS, _) => 16 * KB, + (OS::macOS, _) => 32 * KB, + } + } + + pub fn max_total_tile_memory_allocation(&self) -> u32 { + if self.os() == OS::iOS && self.gpu_family() == 4 { + 32 * KB + } else { + 0 + } + } + + pub fn threadgroup_memory_length_alignment(&self) -> u32 { + 16 + } + + pub fn max_constant_buffer_function_memory_allocation(&self) -> Option<u32> { + if self.os() == OS::macOS { + Some(64 * KB) + } else { + None + } + } + + pub fn max_fragment_inputs(&self) -> u32 { + if self.os() == OS::macOS { + 32 + } else { + 60 + } + } + + pub fn max_fragment_input_components(&self) -> u32 { + if self.os() == OS::macOS { + 128 + } else { + 60 + } + } + + pub fn max_function_constants(&self) -> u32 { + match self.os() { + OS::iOS if self.os_version() >= 11 => 65536, + OS::tvOS if self.os_version() >= 10 => 65536, + OS::macOS if self.os_version() >= 12 => 65536, + _ => 0, + } + } + + pub fn max_tessellation_factor(&self) -> u32 { + if self.supports_tessellation() { + match self.os() { + OS::iOS if self.gpu_family() >= 5 => 64, + OS::iOS => 16, + OS::tvOS => 16, + OS::macOS => 64, + } + } else { + 0 + } + } + + pub fn max_viewports_and_scissor_rectangles(&self) -> u32 { + if self.supports_multiple_viewports() { + 16 + } else { + 1 + } + } + + pub fn max_raster_order_groups(&self) -> u32 { + if self.supports_raster_order_groups() { + 8 + } else { + 0 + } + } + + pub fn max_buffer_length(&self) -> u32 { + if self.os() == OS::macOS && self.os_version() >= 12 { + 1 * GB + } else { + 256 * MB + } + } + + pub fn min_buffer_offset_alignment(&self) -> u32 { + if self.os() == OS::macOS { + 256 + } else { + 4 + } + } + + pub fn max_1d_texture_size(&self) -> u32 { + match (self.os(), self.gpu_family()) { + (OS::iOS, 1) | (OS::iOS, 2) => { + if self.version() <= 2 { + 4096 + } else { + 8192 + } + } + (OS::tvOS, 1) => 8192, + _ => 16384, + } + } + + pub fn max_2d_texture_size(&self) -> u32 { + match (self.os(), self.gpu_family()) { + (OS::iOS, 1) | (OS::iOS, 2) => { + if self.version() <= 2 { + 4096 + } else { + 8192 + } + } + (OS::tvOS, 1) => 8192, + _ => 16384, + } + } + + pub fn max_cube_map_texture_size(&self) -> u32 { + match (self.os(), self.gpu_family()) { + (OS::iOS, 1) | (OS::iOS, 2) => { + if self.version() <= 2 { + 4096 + } else { + 8192 + } + } + (OS::tvOS, 1) => 8192, + _ => 16384, + } + } + + pub fn max_3d_texture_size(&self) -> u32 { + 2048 + } + + pub fn max_array_layers(&self) -> u32 { + 2048 + } + + pub fn copy_texture_buffer_alignment(&self) -> u32 { + match (self.os(), self.gpu_family()) { + (OS::iOS, 1) | (OS::iOS, 2) | (OS::tvOS, 1) => 64, + (OS::iOS, _) | (OS::tvOS, _) => 16, + (OS::macOS, _) => 256, + } + } + + /// If this function returns `None` but linear textures are supported, + /// the buffer alignment can be discovered via API query + pub fn new_texture_buffer_alignment(&self) -> Option<u32> { + match self.os() { + OS::iOS => { + if self.os_version() >= 11 { + None + } else if self.gpu_family() == 3 { + Some(16) + } else { + Some(64) + } + } + OS::tvOS => { + if self.os_version() >= 11 { + None + } else { + Some(64) + } + } + OS::macOS => None, + } + } + + pub fn max_color_render_targets(&self) -> u32 { + if self.os() == OS::iOS && self.gpu_family() == 1 { + 4 + } else { + 8 + } + } + + pub fn max_point_primitive_size(&self) -> u32 { + 511 + } + + pub fn max_total_color_render_target_size(&self) -> Option<u32> { + match (self.os(), self.gpu_family()) { + (OS::iOS, 1) => Some(128), + (OS::iOS, 2) | (OS::iOS, 3) => Some(256), + (OS::iOS, _) => Some(512), + (OS::tvOS, _) => Some(256), + (OS::macOS, _) => None, + } + } + + pub fn max_visibility_query_offset(&self) -> u32 { + 64 * KB - 8 + } + + pub fn a8_unorm_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Filter + } + + pub fn r8_unorm_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn r8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else if self.supports_srgb_writes() { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn r8_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.gpu_family() == 1 { + !PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::all() + } + } + + pub fn r8_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn r8_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn r16_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() != OS::macOS { + !PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::all() + } + } + + pub fn r16_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() != OS::macOS { + !PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::all() + } + } + + pub fn r16_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn r16_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn r16_float_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn rg8_unorm_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn rg8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else if self.supports_srgb_writes() { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rg8_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.gpu_family() == 1 { + !PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::all() + } + } + + pub fn rg8_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rg8_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn b5_g6_r5_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn a1_bgr5_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn abgr4_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn bgr5_a1_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::empty() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn r32_uint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn r32_sint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn r32_float_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Blend + | PixelFormatCapabilities::Msaa + } else if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Blend + | PixelFormatCapabilities::Msaa + } + } + + pub fn rg16_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Resolve + } + } + + pub fn rg16_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Resolve + } + } + + pub fn rg16_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rg16_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rg16_float_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn rgba8_unorm_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn rgba8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_srgb_writes() { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgba8_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.gpu_family() == 1 { + !PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::all() + } + } + + pub fn rgba8_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rgba8_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn bgra8_unorm_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn bgra8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_srgb_writes() { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgb10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities { + let supports_writes = match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + }; + if supports_writes { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgb10_a2_uint_capabilities(&self) -> PixelFormatCapabilities { + let supports_writes = match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + }; + if supports_writes { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Msaa + } + } + + pub fn rg11_b10_float_capabilities(&self) -> PixelFormatCapabilities { + let supports_writes = match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => true, + }; + if supports_writes { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgb9_e5_float_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::Filter + } else { + let supports_writes = match self.os() { + OS::iOS => self.gpu_family() >= 3, + OS::tvOS => self.gpu_family() >= 2, + OS::macOS => false, + }; + if supports_writes { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + } + + pub fn rg32_uint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn rg32_sint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn rg32_float_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Blend + } else { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Blend + } + } + + pub fn rgba16_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgba16_snorm_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else { + !PixelFormatCapabilities::Write + } + } + + pub fn rgba16_uint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rgba16_sint_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Write + | PixelFormatCapabilities::Color + | PixelFormatCapabilities::Msaa + } + + pub fn rgba16_float_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::all() + } + + pub fn rgba32_uint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn rgba32_sint_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::iOS && self.os_version() == 8 { + PixelFormatCapabilities::Color + } else if self.os() == OS::macOS { + PixelFormatCapabilities::Color + | PixelFormatCapabilities::Write + | PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::Color | PixelFormatCapabilities::Write + } + } + + pub fn rgba32_float_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::all() + } else if self.os() == OS::iOS && self.version() == 8 { + PixelFormatCapabilities::Color + } else { + PixelFormatCapabilities::Write | PixelFormatCapabilities::Color + } + } + + pub fn pvrtc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_pvrtc_pixel_formats() { + PixelFormatCapabilities::Filter + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn eac_etc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_eac_etc_pixel_formats() { + PixelFormatCapabilities::Filter + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn astc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_astc_pixel_formats() { + PixelFormatCapabilities::Filter + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn bc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_bc_pixel_formats() { + PixelFormatCapabilities::Filter + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn gbgr422_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Filter + } + + pub fn bgrg422_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Filter + } + + pub fn depth16_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_depth_16_pixel_format() { + PixelFormatCapabilities::Filter + | PixelFormatCapabilities::Msaa + | PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn depth32_float_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::Filter + | PixelFormatCapabilities::Msaa + | PixelFormatCapabilities::Resolve + } else if self.supports_msaa_depth_resolve() { + PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::Msaa + } + } + + pub fn stencil8_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Msaa + } + + pub fn depth24_unorm_stencil8_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::Filter + | PixelFormatCapabilities::Msaa + | PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn depth32_float_stencil8_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::Filter + | PixelFormatCapabilities::Msaa + | PixelFormatCapabilities::Resolve + } else if self.supports_msaa_depth_resolve() { + PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve + } else { + PixelFormatCapabilities::Msaa + } + } + + pub fn x24_stencil8_capabilities(&self) -> PixelFormatCapabilities { + if self.os() == OS::macOS { + PixelFormatCapabilities::Msaa + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn x32_stencil8_capabilities(&self) -> PixelFormatCapabilities { + PixelFormatCapabilities::Msaa + } + + pub fn bgra10_xr_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_extended_range_pixel_formats() { + PixelFormatCapabilities::all() + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn bgra10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_extended_range_pixel_formats() { + PixelFormatCapabilities::all() + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn bgr10_xr_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_extended_range_pixel_formats() { + PixelFormatCapabilities::all() + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn bgr10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_extended_range_pixel_formats() { + PixelFormatCapabilities::all() + } else { + PixelFormatCapabilities::empty() + } + } + + pub fn bgr10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities { + if self.supports_wide_color_pixel_format() { + if self.os() == OS::macOS { + !PixelFormatCapabilities::Write + } else { + PixelFormatCapabilities::all() + } + } else { + PixelFormatCapabilities::empty() + } + } +} + +#[allow(non_camel_case_types)] +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLArgumentBuffersTier { + tier1 = 0, + tier2 = 1, +} + +bitflags! { + struct MTLPipelineOption: NSUInteger { + const ArgumentInfo = 1 << 0; + const BufferTypeInfo = 1 << 1; + } +} + +#[link(name = "Metal", kind = "framework")] +extern "C" { + fn MTLCreateSystemDefaultDevice() -> *mut MTLDevice; + #[cfg(not(target_os = "ios"))] + fn MTLCopyAllDevices() -> *mut Object; //TODO: Array +} + +#[allow(non_camel_case_types)] +type dispatch_data_t = id; +#[allow(non_camel_case_types)] +type dispatch_queue_t = id; +#[allow(non_camel_case_types)] +type dispatch_block_t = *const Block<(), ()>; + +#[cfg_attr( + any(target_os = "macos", target_os = "ios"), + link(name = "System", kind = "dylib") +)] +#[cfg_attr( + not(any(target_os = "macos", target_os = "ios")), + link(name = "dispatch", kind = "dylib") +)] +#[allow(improper_ctypes)] +extern "C" { + static _dispatch_main_q: dispatch_queue_t; + + fn dispatch_data_create( + buffer: *const std::ffi::c_void, + size: crate::c_size_t, + queue: dispatch_queue_t, + destructor: dispatch_block_t, + ) -> dispatch_data_t; + fn dispatch_release(object: dispatch_data_t); // actually dispatch_object_t +} + +/*type MTLNewLibraryCompletionHandler = extern fn(library: id, error: id); +type MTLNewRenderPipelineStateCompletionHandler = extern fn(renderPipelineState: id, error: id); +type MTLNewRenderPipelineStateWithReflectionCompletionHandler = extern fn(renderPipelineState: id, reflection: id, error: id); +type MTLNewComputePipelineStateCompletionHandler = extern fn(computePipelineState: id, error: id); +type MTLNewComputePipelineStateWithReflectionCompletionHandler = extern fn(computePipelineState: id, reflection: id, error: id);*/ + +pub enum MTLDevice {} + +foreign_obj_type! { + type CType = MTLDevice; + pub struct Device; + pub struct DeviceRef; +} + +impl Device { + pub fn system_default() -> Option<Self> { + // `MTLCreateSystemDefaultDevice` may return null if Metal is not supported + unsafe { MTLCreateSystemDefaultDevice().as_mut().map(|x| Self(x)) } + } + + pub fn all() -> Vec<Self> { + #[cfg(target_os = "ios")] + { + Self::system_default().into_iter().collect() + } + #[cfg(not(target_os = "ios"))] + unsafe { + let array = MTLCopyAllDevices(); + let count: NSUInteger = msg_send![array, count]; + let ret = (0..count) + .map(|i| msg_send![array, objectAtIndex: i]) + // The elements of this array are references---we convert them to owned references + // (which just means that we increment the reference count here, and it is + // decremented in the `Drop` impl for `Device`) + .map(|device: *mut Object| msg_send![device, retain]) + .collect(); + let () = msg_send![array, release]; + ret + } + } +} + +impl DeviceRef { + pub fn name(&self) -> &str { + unsafe { + let name = msg_send![self, name]; + crate::nsstring_as_str(name) + } + } + + #[cfg(feature = "private")] + pub unsafe fn vendor(&self) -> &str { + let name = msg_send![self, vendorName]; + crate::nsstring_as_str(name) + } + + #[cfg(feature = "private")] + pub unsafe fn family_name(&self) -> &str { + let name = msg_send![self, familyName]; + crate::nsstring_as_str(name) + } + + pub fn registry_id(&self) -> u64 { + unsafe { msg_send![self, registryID] } + } + + pub fn max_threads_per_threadgroup(&self) -> MTLSize { + unsafe { msg_send![self, maxThreadsPerThreadgroup] } + } + + pub fn is_low_power(&self) -> bool { + unsafe { + match msg_send![self, isLowPower] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn is_headless(&self) -> bool { + unsafe { + match msg_send![self, isHeadless] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn is_removable(&self) -> bool { + unsafe { + match msg_send![self, isRemovable] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn supports_feature_set(&self, feature: MTLFeatureSet) -> bool { + unsafe { + match msg_send![self, supportsFeatureSet: feature] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn supports_vertex_amplification_count(&self, count: NSUInteger) -> bool { + unsafe { + match msg_send![self, supportsVertexAmplificationCount: count] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn supports_sample_count(&self, count: NSUInteger) -> bool { + unsafe { + match msg_send![self, supportsTextureSampleCount: count] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn d24_s8_supported(&self) -> bool { + unsafe { + match msg_send![self, isDepth24Stencil8PixelFormatSupported] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn new_command_queue(&self) -> CommandQueue { + unsafe { msg_send![self, newCommandQueue] } + } + + pub fn new_command_queue_with_max_command_buffer_count( + &self, + count: NSUInteger, + ) -> CommandQueue { + unsafe { msg_send![self, newCommandQueueWithMaxCommandBufferCount: count] } + } + + pub fn new_default_library(&self) -> Library { + unsafe { msg_send![self, newDefaultLibrary] } + } + + pub fn new_library_with_source( + &self, + src: &str, + options: &CompileOptionsRef, + ) -> Result<Library, String> { + use cocoa_foundation::base::nil as cocoa_nil; + use cocoa_foundation::foundation::NSString as cocoa_NSString; + + unsafe { + let source = cocoa_NSString::alloc(cocoa_nil).init_str(src); + let mut err: *mut Object = ptr::null_mut(); + let library: *mut MTLLibrary = msg_send![self, newLibraryWithSource:source + options:options + error:&mut err]; + let () = msg_send![source, release]; + if !err.is_null() { + let desc: *mut Object = msg_send![err, localizedDescription]; + let compile_error: *const std::os::raw::c_char = msg_send![desc, UTF8String]; + let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned(); + if library.is_null() { + let () = msg_send![err, release]; + return Err(message); + } else { + warn!("Shader warnings: {}", message); + } + } + + assert!(!library.is_null()); + Ok(Library::from_ptr(library)) + } + } + + pub fn new_library_with_file<P: AsRef<Path>>(&self, file: P) -> Result<Library, String> { + use cocoa_foundation::base::nil as cocoa_nil; + use cocoa_foundation::foundation::NSString as cocoa_NSString; + + unsafe { + let filename = + cocoa_NSString::alloc(cocoa_nil).init_str(file.as_ref().to_string_lossy().as_ref()); + + let library: *mut MTLLibrary = try_objc! { err => + msg_send![self, newLibraryWithFile:filename.as_ref() + error:&mut err] + }; + + Ok(Library::from_ptr(library)) + } + } + + pub fn new_library_with_data(&self, library_data: &[u8]) -> Result<Library, String> { + unsafe { + let destructor_block = ConcreteBlock::new(|| {}).copy(); + let data = dispatch_data_create( + library_data.as_ptr() as *const std::ffi::c_void, + library_data.len() as crate::c_size_t, + &_dispatch_main_q as *const _ as dispatch_queue_t, + &*destructor_block.deref(), + ); + + let library: *mut MTLLibrary = try_objc! { err => + msg_send![self, newLibraryWithData:data + error:&mut err] + }; + dispatch_release(data); + Ok(Library::from_ptr(library)) + } + } + + pub fn new_render_pipeline_state_with_reflection( + &self, + descriptor: &RenderPipelineDescriptorRef, + reflection: &RenderPipelineReflectionRef, + ) -> Result<RenderPipelineState, String> { + unsafe { + let reflection_options = + MTLPipelineOption::ArgumentInfo | MTLPipelineOption::BufferTypeInfo; + + let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err => + msg_send![self, newRenderPipelineStateWithDescriptor:descriptor + options:reflection_options + reflection:reflection + error:&mut err] + }; + + Ok(RenderPipelineState::from_ptr(pipeline_state)) + } + } + + pub fn new_render_pipeline_state( + &self, + descriptor: &RenderPipelineDescriptorRef, + ) -> Result<RenderPipelineState, String> { + unsafe { + let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err => + msg_send![self, newRenderPipelineStateWithDescriptor:descriptor + error:&mut err] + }; + + Ok(RenderPipelineState::from_ptr(pipeline_state)) + } + } + + pub fn new_compute_pipeline_state_with_function( + &self, + function: &FunctionRef, + ) -> Result<ComputePipelineState, String> { + unsafe { + let pipeline_state: *mut MTLComputePipelineState = try_objc! { err => + msg_send![self, newComputePipelineStateWithFunction:function + error:&mut err] + }; + + Ok(ComputePipelineState::from_ptr(pipeline_state)) + } + } + + pub fn new_compute_pipeline_state( + &self, + descriptor: &ComputePipelineDescriptorRef, + ) -> Result<ComputePipelineState, String> { + unsafe { + let pipeline_state: *mut MTLComputePipelineState = try_objc! { err => + msg_send![self, newComputePipelineStateWithDescriptor:descriptor + error:&mut err] + }; + + Ok(ComputePipelineState::from_ptr(pipeline_state)) + } + } + + pub fn new_buffer(&self, length: u64, options: MTLResourceOptions) -> Buffer { + unsafe { + msg_send![self, newBufferWithLength:length + options:options] + } + } + + pub fn new_buffer_with_data( + &self, + bytes: *const std::ffi::c_void, + length: NSUInteger, + options: MTLResourceOptions, + ) -> Buffer { + unsafe { + msg_send![self, newBufferWithBytes:bytes + length:length + options:options] + } + } + + pub fn new_texture(&self, descriptor: &TextureDescriptorRef) -> Texture { + unsafe { msg_send![self, newTextureWithDescriptor: descriptor] } + } + + pub fn new_sampler(&self, descriptor: &SamplerDescriptorRef) -> SamplerState { + unsafe { msg_send![self, newSamplerStateWithDescriptor: descriptor] } + } + + pub fn new_depth_stencil_state( + &self, + descriptor: &DepthStencilDescriptorRef, + ) -> DepthStencilState { + unsafe { msg_send![self, newDepthStencilStateWithDescriptor: descriptor] } + } + + pub fn argument_buffers_support(&self) -> Option<MTLArgumentBuffersTier> { + unsafe { + let has_arg_buffers: BOOL = + msg_send![self, respondsToSelector: sel!(argumentBuffersSupport)]; + if has_arg_buffers == YES { + Some(msg_send![self, argumentBuffersSupport]) + } else { + None + } + } + } + + pub fn new_argument_encoder( + &self, + arguments: &ArrayRef<ArgumentDescriptor>, + ) -> ArgumentEncoder { + unsafe { msg_send![self, newArgumentEncoderWithArguments: arguments] } + } + + pub fn new_heap(&self, descriptor: &HeapDescriptorRef) -> Heap { + unsafe { msg_send![self, newHeapWithDescriptor: descriptor] } + } + + pub fn heap_buffer_size_and_align( + &self, + length: NSUInteger, + options: MTLResourceOptions, + ) -> MTLSizeAndAlign { + unsafe { msg_send![self, heapBufferSizeAndAlignWithLength: length options: options] } + } + + pub fn heap_texture_size_and_align( + &self, + descriptor: &TextureDescriptorRef, + ) -> MTLSizeAndAlign { + unsafe { msg_send![self, heapTextureSizeAndAlignWithDescriptor: descriptor] } + } + + pub fn minimum_linear_texture_alignment_for_pixel_format( + &self, + format: MTLPixelFormat, + ) -> NSUInteger { + unsafe { msg_send![self, minimumLinearTextureAlignmentForPixelFormat: format] } + } + + pub fn minimum_texture_buffer_alignment_for_pixel_format( + &self, + format: MTLPixelFormat, + ) -> NSUInteger { + unsafe { msg_send![self, minimumTextureBufferAlignmentForPixelFormat: format] } + } + + pub fn max_argument_buffer_sampler_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxArgumentBufferSamplerCount] } + } +} diff --git a/third_party/rust/metal/src/drawable.rs b/third_party/rust/metal/src/drawable.rs new file mode 100644 index 0000000000..0e6d8377c4 --- /dev/null +++ b/third_party/rust/metal/src/drawable.rs @@ -0,0 +1,20 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +pub enum MTLDrawable {} + +foreign_obj_type! { + type CType = MTLDrawable; + pub struct Drawable; + pub struct DrawableRef; +} + +impl DrawableRef { + pub fn present(&self) { + unsafe { msg_send![self, present] } + } +} diff --git a/third_party/rust/metal/src/encoder.rs b/third_party/rust/metal/src/encoder.rs new file mode 100644 index 0000000000..ba9d664d99 --- /dev/null +++ b/third_party/rust/metal/src/encoder.rs @@ -0,0 +1,1121 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::{NSInteger, NSRange, NSUInteger}; + +use std::ops::Range; + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLPrimitiveType { + Point = 0, + Line = 1, + LineStrip = 2, + Triangle = 3, + TriangleStrip = 4, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLIndexType { + UInt16 = 0, + UInt32 = 1, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLVisibilityResultMode { + Disabled = 0, + Boolean = 1, + Counting = 2, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLCullMode { + None = 0, + Front = 1, + Back = 2, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLWinding { + Clockwise = 0, + CounterClockwise = 1, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLDepthClipMode { + Clip = 0, + Clamp = 1, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLTriangleFillMode { + Fill = 0, + Lines = 1, +} + +bitflags! { + #[allow(non_upper_case_globals)] + pub struct MTLBlitOption: NSUInteger { + const DepthFromDepthStencil = 1 << 0; + const StencilFromDepthStencil = 1 << 1; + const RowLinearPVRTC = 1 << 2; + } +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLScissorRect { + pub x: NSUInteger, + pub y: NSUInteger, + pub width: NSUInteger, + pub height: NSUInteger, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLViewport { + pub originX: f64, + pub originY: f64, + pub width: f64, + pub height: f64, + pub znear: f64, + pub zfar: f64, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLDrawPrimitivesIndirectArguments { + pub vertexCount: u32, + pub instanceCount: u32, + pub vertexStart: u32, + pub baseInstance: u32, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLDrawIndexedPrimitivesIndirectArguments { + pub indexCount: u32, + pub instanceCount: u32, + pub indexStart: u32, + pub baseVertex: i32, + pub baseInstance: u32, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct VertexAmplificationViewMapping { + pub renderTargetArrayIndexOffset: u32, + pub viewportArrayIndexOffset: u32, +} + +pub enum MTLCommandEncoder {} + +foreign_obj_type! { + type CType = MTLCommandEncoder; + pub struct CommandEncoder; + pub struct CommandEncoderRef; +} + +impl CommandEncoderRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + msg_send![self, setLabel: nslabel] + } + } + + pub fn end_encoding(&self) { + unsafe { msg_send![self, endEncoding] } + } + + pub fn insert_debug_signpost(&self, name: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(name); + msg_send![self, insertDebugSignpost: nslabel] + } + } + + pub fn push_debug_group(&self, name: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(name); + msg_send![self, pushDebugGroup: nslabel] + } + } + + pub fn pop_debug_group(&self) { + unsafe { msg_send![self, popDebugGroup] } + } +} + +pub enum MTLParallelRenderCommandEncoder {} + +foreign_obj_type! { + type CType = MTLParallelRenderCommandEncoder; + pub struct ParallelRenderCommandEncoder; + pub struct ParallelRenderCommandEncoderRef; + type ParentType = CommandEncoderRef; +} + +impl ParallelRenderCommandEncoderRef { + pub fn render_command_encoder(&self) -> &RenderCommandEncoderRef { + unsafe { msg_send![self, renderCommandEncoder] } + } +} + +pub enum MTLRenderCommandEncoder {} + +foreign_obj_type! { + type CType = MTLRenderCommandEncoder; + pub struct RenderCommandEncoder; + pub struct RenderCommandEncoderRef; + type ParentType = CommandEncoderRef; +} + +impl RenderCommandEncoderRef { + pub fn set_render_pipeline_state(&self, pipeline_state: &RenderPipelineStateRef) { + unsafe { msg_send![self, setRenderPipelineState: pipeline_state] } + } + + pub fn set_viewport(&self, viewport: MTLViewport) { + unsafe { msg_send![self, setViewport: viewport] } + } + + pub fn set_front_facing_winding(&self, winding: MTLWinding) { + unsafe { msg_send![self, setFrontFacingWinding: winding] } + } + + pub fn set_cull_mode(&self, mode: MTLCullMode) { + unsafe { msg_send![self, setCullMode: mode] } + } + + pub fn set_depth_clip_mode(&self, mode: MTLDepthClipMode) { + unsafe { msg_send![self, setDepthClipMode: mode] } + } + + pub fn set_depth_bias(&self, bias: f32, scale: f32, clamp: f32) { + unsafe { + msg_send![self, setDepthBias:bias + slopeScale:scale + clamp:clamp] + } + } + + pub fn set_scissor_rect(&self, rect: MTLScissorRect) { + unsafe { msg_send![self, setScissorRect: rect] } + } + + pub fn set_triangle_fill_mode(&self, mode: MTLTriangleFillMode) { + unsafe { msg_send![self, setTriangleFillMode: mode] } + } + + pub fn set_blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) { + unsafe { + msg_send![self, setBlendColorRed:red + green:green + blue:blue + alpha:alpha] + } + } + + pub fn set_depth_stencil_state(&self, depth_stencil_state: &DepthStencilStateRef) { + unsafe { msg_send![self, setDepthStencilState: depth_stencil_state] } + } + + pub fn set_stencil_reference_value(&self, value: u32) { + unsafe { msg_send![self, setStencilReferenceValue: value] } + } + + pub fn set_stencil_front_back_reference_value(&self, front: u32, back: u32) { + unsafe { + msg_send![self, setStencilFrontReferenceValue:front + backReferenceValue:back] + } + } + + pub fn set_visibility_result_mode(&self, mode: MTLVisibilityResultMode, offset: NSUInteger) { + unsafe { + msg_send![self, setVisibilityResultMode:mode + offset:offset] + } + } + + pub fn set_vertex_amplification_count( + &self, + count: NSUInteger, + view_mappings: Option<&[VertexAmplificationViewMapping]>, + ) { + unsafe { + msg_send! [self, setVertexAmplificationCount: count viewMappings: view_mappings.map_or(std::ptr::null(), |vm| vm.as_ptr())] + } + } + + // Specifying Resources for a Vertex Shader Function + + pub fn set_vertex_bytes( + &self, + index: NSUInteger, + length: NSUInteger, + bytes: *const std::ffi::c_void, + ) { + unsafe { + msg_send![self, + setVertexBytes:bytes + length:length + atIndex:index + ] + } + } + + pub fn set_vertex_buffer( + &self, + index: NSUInteger, + buffer: Option<&BufferRef>, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setVertexBuffer:buffer + offset:offset + atIndex:index + ] + } + } + + pub fn set_vertex_buffer_offset(&self, index: NSUInteger, offset: NSUInteger) { + unsafe { + msg_send![self, + setVertexBufferOffset:offset + atIndex:index + ] + } + } + + pub fn set_vertex_buffers( + &self, + start_index: NSUInteger, + data: &[Option<&BufferRef>], + offsets: &[NSUInteger], + ) { + debug_assert_eq!(offsets.len(), data.len()); + unsafe { + msg_send![self, + setVertexBuffers: data.as_ptr() + offsets: offsets.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_vertex_texture(&self, index: NSUInteger, texture: Option<&TextureRef>) { + unsafe { + msg_send![self, + setVertexTexture:texture + atIndex:index + ] + } + } + + pub fn set_vertex_textures(&self, start_index: NSUInteger, data: &[Option<&TextureRef>]) { + unsafe { + msg_send![self, + setVertexTextures: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_vertex_sampler_state(&self, index: NSUInteger, sampler: Option<&SamplerStateRef>) { + unsafe { + msg_send![self, + setVertexSamplerState:sampler + atIndex:index + ] + } + } + + pub fn set_vertex_sampler_states( + &self, + start_index: NSUInteger, + data: &[Option<&SamplerStateRef>], + ) { + unsafe { + msg_send![self, + setVertexSamplerStates: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_vertex_sampler_state_with_lod( + &self, + index: NSUInteger, + sampler: Option<&SamplerStateRef>, + lod_clamp: Range<f32>, + ) { + unsafe { + msg_send![self, + setVertexSamplerState:sampler + lodMinClamp:lod_clamp.start + lodMaxClamp:lod_clamp.end + atIndex:index + ] + } + } + + // Specifying Resources for a Fragment Shader Function + + pub fn set_fragment_bytes( + &self, + index: NSUInteger, + length: NSUInteger, + bytes: *const std::ffi::c_void, + ) { + unsafe { + msg_send![self, + setFragmentBytes:bytes + length:length + atIndex:index + ] + } + } + + pub fn set_fragment_buffer( + &self, + index: NSUInteger, + buffer: Option<&BufferRef>, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setFragmentBuffer:buffer + offset:offset + atIndex:index + ] + } + } + + pub fn set_fragment_buffer_offset(&self, index: NSUInteger, offset: NSUInteger) { + unsafe { + msg_send![self, + setFragmentBufferOffset:offset + atIndex:index + ] + } + } + + pub fn set_fragment_buffers( + &self, + start_index: NSUInteger, + data: &[Option<&BufferRef>], + offsets: &[NSUInteger], + ) { + debug_assert_eq!(offsets.len(), data.len()); + unsafe { + msg_send![self, + setFragmentBuffers: data.as_ptr() + offsets: offsets.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_fragment_texture(&self, index: NSUInteger, texture: Option<&TextureRef>) { + unsafe { + msg_send![self, + setFragmentTexture:texture + atIndex:index + ] + } + } + + pub fn set_fragment_textures(&self, start_index: NSUInteger, data: &[Option<&TextureRef>]) { + unsafe { + msg_send![self, + setFragmentTextures: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_fragment_sampler_state(&self, index: NSUInteger, sampler: Option<&SamplerStateRef>) { + unsafe { + msg_send![self, setFragmentSamplerState:sampler + atIndex:index] + } + } + + pub fn set_fragment_sampler_states( + &self, + start_index: NSUInteger, + data: &[Option<&SamplerStateRef>], + ) { + unsafe { + msg_send![self, + setFragmentSamplerStates: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_fragment_sampler_state_with_lod( + &self, + index: NSUInteger, + sampler: Option<&SamplerStateRef>, + lod_clamp: Range<f32>, + ) { + unsafe { + msg_send![self, + setFragmentSamplerState:sampler + lodMinClamp:lod_clamp.start + lodMaxClamp:lod_clamp.end + atIndex:index + ] + } + } + + // Drawing Geometric Primitives + + pub fn draw_primitives( + &self, + primitive_type: MTLPrimitiveType, + vertex_start: NSUInteger, + vertex_count: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPrimitives: primitive_type + vertexStart: vertex_start + vertexCount: vertex_count + ] + } + } + + pub fn draw_primitives_instanced( + &self, + primitive_type: MTLPrimitiveType, + vertex_start: NSUInteger, + vertex_count: NSUInteger, + instance_count: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPrimitives: primitive_type + vertexStart: vertex_start + vertexCount: vertex_count + instanceCount: instance_count + ] + } + } + + pub fn draw_primitives_instanced_base_instance( + &self, + primitive_type: MTLPrimitiveType, + vertex_start: NSUInteger, + vertex_count: NSUInteger, + instance_count: NSUInteger, + base_instance: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPrimitives: primitive_type + vertexStart: vertex_start + vertexCount: vertex_count + instanceCount: instance_count + baseInstance: base_instance + ] + } + } + + pub fn draw_primitives_indirect( + &self, + primitive_type: MTLPrimitiveType, + indirect_buffer: &BufferRef, + indirect_buffer_offset: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPrimitives: primitive_type + indirectBuffer: indirect_buffer + indirectBufferOffset: indirect_buffer_offset + ] + } + } + + pub fn draw_indexed_primitives( + &self, + primitive_type: MTLPrimitiveType, + index_count: NSUInteger, + index_type: MTLIndexType, + index_buffer: &BufferRef, + index_buffer_offset: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPrimitives: primitive_type + indexCount: index_count + indexType: index_type + indexBuffer: index_buffer + indexBufferOffset: index_buffer_offset + ] + } + } + + pub fn draw_indexed_primitives_instanced( + &self, + primitive_type: MTLPrimitiveType, + index_count: NSUInteger, + index_type: MTLIndexType, + index_buffer: &BufferRef, + index_buffer_offset: NSUInteger, + instance_count: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPrimitives: primitive_type + indexCount: index_count + indexType: index_type + indexBuffer: index_buffer + indexBufferOffset: index_buffer_offset + instanceCount: instance_count + ] + } + } + + pub fn draw_indexed_primitives_instanced_base_instance( + &self, + primitive_type: MTLPrimitiveType, + index_count: NSUInteger, + index_type: MTLIndexType, + index_buffer: &BufferRef, + index_buffer_offset: NSUInteger, + instance_count: NSUInteger, + base_vertex: NSInteger, + base_instance: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPrimitives: primitive_type + indexCount: index_count + indexType: index_type + indexBuffer: index_buffer + indexBufferOffset: index_buffer_offset + instanceCount: instance_count + baseVertex: base_vertex + baseInstance: base_instance + ] + } + } + + pub fn draw_indexed_primitives_indirect( + &self, + primitive_type: MTLPrimitiveType, + index_type: MTLIndexType, + index_buffer: &BufferRef, + index_buffer_offset: NSUInteger, + indirect_buffer: &BufferRef, + indirect_buffer_offset: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPrimitives: primitive_type + indexType: index_type + indexBuffer: index_buffer + indexBufferOffset: index_buffer_offset + indirectBuffer: indirect_buffer + indirectBufferOffset: indirect_buffer_offset + ] + } + } + + // TODO: more draws + // fn setVertexBufferOffset_atIndex(self, offset: NSUInteger, index: NSUInteger); + // fn setVertexBuffers_offsets_withRange(self, buffers: *const id, offsets: *const NSUInteger, range: NSRange); + // fn setVertexSamplerStates_lodMinClamps_lodMaxClamps_withRange(self, samplers: *const id, lodMinClamps: *const f32, lodMaxClamps: *const f32, range: NSRange); + + pub fn use_resource(&self, resource: &ResourceRef, usage: MTLResourceUsage) { + unsafe { + msg_send![self, useResource:resource + usage:usage] + } + } + + pub fn use_heap(&self, heap: &HeapRef) { + unsafe { msg_send![self, useHeap: heap] } + } +} + +pub enum MTLBlitCommandEncoder {} + +foreign_obj_type! { + type CType = MTLBlitCommandEncoder; + pub struct BlitCommandEncoder; + pub struct BlitCommandEncoderRef; + type ParentType = CommandEncoderRef; +} + +impl BlitCommandEncoderRef { + pub fn synchronize_resource(&self, resource: &ResourceRef) { + unsafe { msg_send![self, synchronizeResource: resource] } + } + + pub fn fill_buffer(&self, destination_buffer: &BufferRef, range: NSRange, value: u8) { + unsafe { + msg_send![self, + fillBuffer: destination_buffer + range: range + value: value + ] + } + } + + pub fn copy_from_buffer( + &self, + source_buffer: &BufferRef, + source_offset: NSUInteger, + destination_buffer: &BufferRef, + destination_offset: NSUInteger, + size: NSUInteger, + ) { + unsafe { + msg_send![self, + copyFromBuffer: source_buffer + sourceOffset: source_offset + toBuffer: destination_buffer + destinationOffset: destination_offset + size: size + ] + } + } + + pub fn copy_from_texture( + &self, + source_texture: &TextureRef, + source_slice: NSUInteger, + source_level: NSUInteger, + source_origin: MTLOrigin, + source_size: MTLSize, + destination_texture: &TextureRef, + destination_slice: NSUInteger, + destination_level: NSUInteger, + destination_origin: MTLOrigin, + ) { + unsafe { + msg_send![self, + copyFromTexture: source_texture + sourceSlice: source_slice + sourceLevel: source_level + sourceOrigin: source_origin + sourceSize: source_size + toTexture: destination_texture + destinationSlice: destination_slice + destinationLevel: destination_level + destinationOrigin: destination_origin + ] + } + } + + pub fn copy_from_buffer_to_texture( + &self, + source_buffer: &BufferRef, + source_offset: NSUInteger, + source_bytes_per_row: NSUInteger, + source_bytes_per_image: NSUInteger, + source_size: MTLSize, + destination_texture: &TextureRef, + destination_slice: NSUInteger, + destination_level: NSUInteger, + destination_origin: MTLOrigin, + options: MTLBlitOption, + ) { + unsafe { + msg_send![self, + copyFromBuffer: source_buffer + sourceOffset: source_offset + sourceBytesPerRow: source_bytes_per_row + sourceBytesPerImage: source_bytes_per_image + sourceSize: source_size + toTexture: destination_texture + destinationSlice: destination_slice + destinationLevel: destination_level + destinationOrigin: destination_origin + options: options + ] + } + } + + pub fn copy_from_texture_to_buffer( + &self, + source_texture: &TextureRef, + source_slice: NSUInteger, + source_level: NSUInteger, + source_origin: MTLOrigin, + source_size: MTLSize, + destination_buffer: &BufferRef, + destination_offset: NSUInteger, + destination_bytes_per_row: NSUInteger, + destination_bytes_per_image: NSUInteger, + options: MTLBlitOption, + ) { + unsafe { + msg_send![self, + copyFromTexture: source_texture + sourceSlice: source_slice + sourceLevel: source_level + sourceOrigin: source_origin + sourceSize: source_size + toBuffer: destination_buffer + destinationOffset: destination_offset + destinationBytesPerRow: destination_bytes_per_row + destinationBytesPerImage: destination_bytes_per_image + options: options + ] + } + } + + pub fn optimize_contents_for_gpu_access(&self, texture: &TextureRef) { + unsafe { msg_send![self, optimizeContentsForGPUAccess: texture] } + } + + pub fn optimize_contents_for_gpu_access_slice_level( + &self, + texture: &TextureRef, + slice: NSUInteger, + level: NSUInteger, + ) { + unsafe { + msg_send![self, + optimizeContentsForGPUAccess: texture + slice: slice + level: level + ] + } + } + + pub fn optimize_contents_for_cpu_access(&self, texture: &TextureRef) { + unsafe { msg_send![self, optimizeContentsForCPUAccess: texture] } + } + + pub fn optimize_contents_for_cpu_access_slice_level( + &self, + texture: &TextureRef, + slice: NSUInteger, + level: NSUInteger, + ) { + unsafe { + msg_send![self, + optimizeContentsForCPUAccess: texture + slice: slice + level: level + ] + } + } +} + +pub enum MTLComputeCommandEncoder {} + +foreign_obj_type! { + type CType = MTLComputeCommandEncoder; + pub struct ComputeCommandEncoder; + pub struct ComputeCommandEncoderRef; + type ParentType = CommandEncoderRef; +} + +impl ComputeCommandEncoderRef { + pub fn set_compute_pipeline_state(&self, state: &ComputePipelineStateRef) { + unsafe { msg_send![self, setComputePipelineState: state] } + } + + pub fn set_buffer(&self, index: NSUInteger, buffer: Option<&BufferRef>, offset: NSUInteger) { + unsafe { msg_send![self, setBuffer:buffer offset:offset atIndex:index] } + } + + pub fn set_buffers( + &self, + start_index: NSUInteger, + data: &[Option<&BufferRef>], + offsets: &[NSUInteger], + ) { + debug_assert_eq!(offsets.len(), data.len()); + unsafe { + msg_send![self, + setBuffers: data.as_ptr() + offsets: offsets.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_texture(&self, index: NSUInteger, texture: Option<&TextureRef>) { + unsafe { + msg_send![self, + setTexture:texture + atIndex:index + ] + } + } + + pub fn set_textures(&self, start_index: NSUInteger, data: &[Option<&TextureRef>]) { + unsafe { + msg_send![self, + setTextures: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_sampler_state(&self, index: NSUInteger, sampler: Option<&SamplerStateRef>) { + unsafe { + msg_send![self, + setSamplerState:sampler + atIndex:index + ] + } + } + + pub fn set_sampler_states(&self, start_index: NSUInteger, data: &[Option<&SamplerStateRef>]) { + unsafe { + msg_send![self, + setSamplerStates: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_sampler_state_with_lod( + &self, + index: NSUInteger, + sampler: Option<&SamplerStateRef>, + lod_clamp: Range<f32>, + ) { + unsafe { + msg_send![self, + setSamplerState:sampler + lodMinClamp:lod_clamp.start + lodMaxClamp:lod_clamp.end + atIndex:index + ] + } + } + + pub fn set_bytes(&self, index: NSUInteger, length: NSUInteger, bytes: *const std::ffi::c_void) { + unsafe { + msg_send![self, + setBytes: bytes + length: length + atIndex: index + ] + } + } + + pub fn dispatch_thread_groups( + &self, + thread_groups_count: MTLSize, + threads_per_thread_group: MTLSize, + ) { + unsafe { + msg_send![self, + dispatchThreadgroups:thread_groups_count + threadsPerThreadgroup:threads_per_thread_group + ] + } + } + + pub fn dispatch_thread_groups_indirect( + &self, + buffer: &BufferRef, + offset: NSUInteger, + threads_per_thread_group: MTLSize, + ) { + unsafe { + msg_send![self, + dispatchThreadgroupsWithIndirectBuffer:buffer + indirectBufferOffset:offset + threadsPerThreadgroup:threads_per_thread_group + ] + } + } + + pub fn use_resource(&self, resource: &ResourceRef, usage: MTLResourceUsage) { + unsafe { + msg_send![self, + useResource:resource + usage:usage + ] + } + } + + pub fn use_heap(&self, heap: &HeapRef) { + unsafe { msg_send![self, useHeap: heap] } + } +} + +pub enum MTLArgumentEncoder {} + +foreign_obj_type! { + type CType = MTLArgumentEncoder; + pub struct ArgumentEncoder; + pub struct ArgumentEncoderRef; +} + +impl ArgumentEncoderRef { + pub fn encoded_length(&self) -> NSUInteger { + unsafe { msg_send![self, encodedLength] } + } + + pub fn alignment(&self) -> NSUInteger { + unsafe { msg_send![self, alignment] } + } + + pub fn set_argument_buffer(&self, buffer: &BufferRef, offset: NSUInteger) { + unsafe { + msg_send![self, + setArgumentBuffer: buffer + offset: offset + ] + } + } + + pub fn set_argument_buffer_to_element( + &self, + array_element: NSUInteger, + buffer: &BufferRef, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setArgumentBuffer: buffer + startOffset: offset + arrayElement: array_element + ] + } + } + + pub fn set_buffer(&self, at_index: NSUInteger, buffer: &BufferRef, offset: NSUInteger) { + unsafe { + msg_send![self, + setBuffer: buffer + offset: offset + atIndex: at_index + ] + } + } + + pub fn set_buffers( + &self, + start_index: NSUInteger, + data: &[&BufferRef], + offsets: &[NSUInteger], + ) { + assert_eq!(offsets.len(), data.len()); + unsafe { + msg_send![self, + setBuffers: data.as_ptr() + offsets: offsets.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_texture(&self, at_index: NSUInteger, texture: &TextureRef) { + unsafe { + msg_send![self, + setTexture: texture + atIndex: at_index + ] + } + } + + pub fn set_textures(&self, start_index: NSUInteger, data: &[&TextureRef]) { + unsafe { + msg_send![self, + setTextures: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn set_sampler_state(&self, at_index: NSUInteger, sampler_state: &SamplerStateRef) { + unsafe { + msg_send![self, + setSamplerState: sampler_state + atIndex: at_index + ] + } + } + + pub fn set_sampler_states(&self, start_index: NSUInteger, data: &[&SamplerStateRef]) { + unsafe { + msg_send![self, + setSamplerStates: data.as_ptr() + withRange: NSRange { + location: start_index, + length: data.len() as _, + } + ] + } + } + + pub fn constant_data(&self, at_index: NSUInteger) -> *mut std::ffi::c_void { + unsafe { msg_send![self, constantDataAtIndex: at_index] } + } + + pub fn new_argument_encoder_for_buffer(&self, index: NSUInteger) -> ArgumentEncoder { + unsafe { + let ptr = msg_send![self, newArgumentEncoderForBufferAtIndex: index]; + ArgumentEncoder::from_ptr(ptr) + } + } +} diff --git a/third_party/rust/metal/src/heap.rs b/third_party/rust/metal/src/heap.rs new file mode 100644 index 0000000000..9adb51c681 --- /dev/null +++ b/third_party/rust/metal/src/heap.rs @@ -0,0 +1,110 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSUInteger; + +pub enum MTLHeap {} + +foreign_obj_type! { + type CType = MTLHeap; + pub struct Heap; + pub struct HeapRef; +} + +impl HeapRef { + pub fn cpu_cache_mode(&self) -> MTLCPUCacheMode { + unsafe { msg_send![self, cpuCacheMode] } + } + + pub fn storage_mode(&self) -> MTLStorageMode { + unsafe { msg_send![self, storageMode] } + } + + pub fn set_purgeable_state(&self, state: MTLPurgeableState) -> MTLPurgeableState { + unsafe { msg_send![self, setPurgeableState: state] } + } + + pub fn size(&self) -> NSUInteger { + unsafe { msg_send![self, size] } + } + + pub fn used_size(&self) -> NSUInteger { + unsafe { msg_send![self, usedSize] } + } + + pub fn max_available_size(&self, alignment: NSUInteger) -> NSUInteger { + unsafe { msg_send![self, maxAvailableSizeWithAlignment: alignment] } + } + + pub fn new_buffer(&self, length: u64, options: MTLResourceOptions) -> Option<Buffer> { + unsafe { + let ptr: *mut MTLBuffer = msg_send![self, newBufferWithLength:length + options:options]; + if !ptr.is_null() { + Some(Buffer::from_ptr(ptr)) + } else { + None + } + } + } + + pub fn new_texture(&self, descriptor: &TextureDescriptorRef) -> Option<Texture> { + unsafe { + let ptr: *mut MTLTexture = msg_send![self, newTextureWithDescriptor: descriptor]; + if !ptr.is_null() { + Some(Texture::from_ptr(ptr)) + } else { + None + } + } + } +} + +pub enum MTLHeapDescriptor {} + +foreign_obj_type! { + type CType = MTLHeapDescriptor; + pub struct HeapDescriptor; + pub struct HeapDescriptorRef; +} + +impl HeapDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLHeapDescriptor); + msg_send![class, new] + } + } +} + +impl HeapDescriptorRef { + pub fn cpu_cache_mode(&self) -> MTLCPUCacheMode { + unsafe { msg_send![self, cpuCacheMode] } + } + + pub fn set_cpu_cache_mode(&self, mode: MTLCPUCacheMode) { + unsafe { msg_send![self, setCpuCacheMode: mode] } + } + + pub fn storage_mode(&self) -> MTLStorageMode { + unsafe { msg_send![self, storageMode] } + } + + pub fn set_storage_mode(&self, mode: MTLStorageMode) { + unsafe { msg_send![self, setStorageMode: mode] } + } + + pub fn size(&self) -> NSUInteger { + unsafe { msg_send![self, size] } + } + + pub fn set_size(&self, size: NSUInteger) { + unsafe { msg_send![self, setSize: size] } + } +} diff --git a/third_party/rust/metal/src/indirect_encoder.rs b/third_party/rust/metal/src/indirect_encoder.rs new file mode 100644 index 0000000000..3f08ead9bc --- /dev/null +++ b/third_party/rust/metal/src/indirect_encoder.rs @@ -0,0 +1,349 @@ +use super::*; + +use cocoa_foundation::foundation::{NSRange, NSUInteger}; + +bitflags! { + #[allow(non_upper_case_globals)] + pub struct MTLIndirectCommandType: NSUInteger { + const Draw = 1 << 0; + const DrawIndexed = 1 << 1; + const DrawPatches = 1 << 2; + const DrawIndexedPatches = 1 << 3; + const ConcurrentDispatch = 1 << 4; + const ConcurrentDispatchThreads = 1 << 5; + } +} + +pub enum MTLIndirectCommandBufferDescriptor {} + +foreign_obj_type! { + type CType = MTLIndirectCommandBufferDescriptor; + pub struct IndirectCommandBufferDescriptor; + pub struct IndirectCommandBufferDescriptorRef; +} + +impl IndirectCommandBufferDescriptorRef { + pub fn command_types(&self) -> MTLIndirectCommandType { + unsafe { msg_send![self, commandTypes] } + } + + pub fn set_command_types(&self, types: MTLIndirectCommandType) { + unsafe { msg_send![self, setCommandTypes: types] } + } + + pub fn inherit_buffer(&self) -> bool { + unsafe { + match msg_send![self, inheritBuffer] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_inherit_buffer(&self, inherit: bool) { + unsafe { msg_send![self, setInheritBuffer: inherit] } + } + + pub fn inherit_pipeline_state(&self) -> bool { + unsafe { + match msg_send![self, inheritPipelineState] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_inherit_pipeline_state(&self, inherit: bool) { + unsafe { msg_send![self, setInheritPipelineState: inherit] } + } + + pub fn max_vertex_buffer_bind_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxVertexBufferBindCount] } + } + + pub fn set_max_vertex_buffer_bind_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMaxVertexBufferBindCount: count] } + } + + pub fn max_fragment_buffer_bind_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxFragmentBufferBindCount] } + } + + pub fn set_max_fragment_buffer_bind_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMaxFragmentBufferBindCount: count] } + } + + pub fn max_kernel_buffer_bind_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxKernelBufferBindCount] } + } + + pub fn set_max_kernel_buffer_bind_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMaxKernelBufferBindCount: count] } + } +} + +pub enum MTLIndirectCommandBuffer {} + +foreign_obj_type! { + type CType = MTLIndirectCommandBuffer; + pub struct IndirectCommandBuffer; + pub struct IndirectCommandBufferRef; + type ParentType = ResourceRef; +} + +impl IndirectCommandBufferRef { + pub fn size(&self) -> NSUInteger { + unsafe { msg_send![self, size] } + } + + pub fn indirect_render_command_at_index(&self, index: NSUInteger) -> &IndirectRenderCommandRef { + unsafe { msg_send![self, indirectRenderCommandAtIndex: index] } + } + + pub fn indirect_compute_command_at_index( + &self, + index: NSUInteger, + ) -> &IndirectComputeCommandRef { + unsafe { msg_send![self, indirectComputeCommandAtIndex: index] } + } + + pub fn reset_with_range(&self, range: NSRange) { + unsafe { msg_send![self, resetWithRange: range] } + } +} + +pub enum MTLIndirectRenderCommand {} + +foreign_obj_type! { + type CType = MTLIndirectRenderCommand; + pub struct IndirectRenderCommand; + pub struct IndirectRenderCommandRef; +} + +impl IndirectRenderCommandRef { + pub fn set_render_pipeline_state(&self, pipeline_state: &RenderPipelineStateRef) { + unsafe { msg_send![self, setRenderPipelineState: pipeline_state] } + } + + pub fn set_vertex_buffer( + &self, + index: NSUInteger, + buffer: Option<&BufferRef>, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setVertexBuffer: buffer + offset: offset + atIndex: index + ] + } + } + + pub fn set_fragment_buffer( + &self, + index: NSUInteger, + buffer: Option<&BufferRef>, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setFragmentBuffer:buffer + offset:offset + atIndex:index + ] + } + } + + pub fn draw_primitives( + &self, + primitive_type: MTLPrimitiveType, + vertex_start: NSUInteger, + vertex_count: NSUInteger, + instance_count: NSUInteger, + base_instance: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPrimitives: primitive_type + vertexStart: vertex_start + vertexCount: vertex_count + instanceCount: instance_count + baseInstance: base_instance + ] + } + } + + pub fn draw_indexed_primitives( + &self, + primitive_type: MTLPrimitiveType, + index_count: NSUInteger, + index_type: MTLIndexType, + index_buffer: &BufferRef, + index_buffer_offset: NSUInteger, + instance_count: NSUInteger, + base_vertex: NSUInteger, + base_instance: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPrimitives: primitive_type + indexCount: index_count + indexType: index_type + indexBuffer: index_buffer + indexBufferOffset: index_buffer_offset + instanceCount: instance_count + baseVertex: base_vertex + baseInstance: base_instance + ] + } + } + + pub fn draw_patches( + &self, + number_of_patch_control_points: NSUInteger, + patch_start: NSUInteger, + patch_count: NSUInteger, + patch_index_buffer: &BufferRef, + patch_index_buffer_offset: NSUInteger, + instance_count: NSUInteger, + base_instance: NSUInteger, + tesselation_factor_buffer: &BufferRef, + tesselation_factor_buffer_offset: NSUInteger, + tesselation_factor_buffer_instance_stride: NSUInteger, + ) { + unsafe { + msg_send![self, + drawPatches: number_of_patch_control_points + patchStart: patch_start + patchCount: patch_count + patchIndexBuffer: patch_index_buffer + patchIndexBufferOffset: patch_index_buffer_offset + instanceCount: instance_count + baseInstance: base_instance + tessellationFactorBuffer: tesselation_factor_buffer + tessellationFactorBufferOffset: tesselation_factor_buffer_offset + tessellationFactorBufferInstanceStride: tesselation_factor_buffer_instance_stride + ] + } + } + + pub fn draw_indexed_patches( + &self, + number_of_patch_control_points: NSUInteger, + patch_start: NSUInteger, + patch_count: NSUInteger, + patch_index_buffer: &BufferRef, + patch_index_buffer_offset: NSUInteger, + control_point_index_buffer: &BufferRef, + control_point_index_buffer_offset: NSUInteger, + instance_count: NSUInteger, + base_instance: NSUInteger, + tesselation_factor_buffer: &BufferRef, + tesselation_factor_buffer_offset: NSUInteger, + tesselation_factor_buffer_instance_stride: NSUInteger, + ) { + unsafe { + msg_send![self, + drawIndexedPatches: number_of_patch_control_points + patchStart: patch_start + patchCount: patch_count + patchIndexBuffer: patch_index_buffer + patchIndexBufferOffset: patch_index_buffer_offset + controlPointIndexBuffer: control_point_index_buffer + controlPointIndexBufferOffset: control_point_index_buffer_offset + instanceCount: instance_count + baseInstance: base_instance + tessellationFactorBuffer: tesselation_factor_buffer + tessellationFactorBufferOffset: tesselation_factor_buffer_offset + tessellationFactorBufferInstanceStride: tesselation_factor_buffer_instance_stride + ] + } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLIndirectComputeCommand {} + +foreign_obj_type! { + type CType = MTLIndirectComputeCommand; + pub struct IndirectComputeCommand; + pub struct IndirectComputeCommandRef; +} + +impl IndirectComputeCommandRef { + pub fn set_compute_pipeline_state(&self, state: &ComputePipelineStateRef) { + unsafe { msg_send![self, setComputePipelineState: state] } + } + + pub fn set_kernel_buffer( + &self, + index: NSUInteger, + buffer: Option<&BufferRef>, + offset: NSUInteger, + ) { + unsafe { + msg_send![self, + setKernelBuffer: buffer + offset: offset + atIndex: index + ] + } + } + + pub fn set_threadgroup_memory_length(&self, index: NSUInteger, length: NSUInteger) { + unsafe { + msg_send![self, + setThreadgroupMemoryLength: length + atIndex: index + ] + } + } + + pub fn set_stage_in_region(&self, region: MTLRegion) { + unsafe { msg_send![self, setStageInRegion: region] } + } + + pub fn set_barrier(&self) { + unsafe { msg_send![self, setBarrier] } + } + + pub fn clear_barrier(&self) { + unsafe { msg_send![self, clearBarrier] } + } + + pub fn concurrent_dispatch_threadgroups( + &self, + thread_groups_per_grid: MTLSize, + threads_per_threadgroup: MTLSize, + ) { + unsafe { + msg_send![self, + concurrentDispatchThreadgroups: thread_groups_per_grid + threadsPerThreadgroup: threads_per_threadgroup + ] + } + } + + pub fn concurrent_dispatch_threads( + &self, + thread_groups_per_grid: MTLSize, + threads_per_threadgroup: MTLSize, + ) { + unsafe { + msg_send![self, + concurrentDispatchThreads: thread_groups_per_grid + threadsPerThreadgroup: threads_per_threadgroup + ] + } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} diff --git a/third_party/rust/metal/src/lib.rs b/third_party/rust/metal/src/lib.rs new file mode 100644 index 0000000000..e5833da57c --- /dev/null +++ b/third_party/rust/metal/src/lib.rs @@ -0,0 +1,433 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] + +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate log; +#[macro_use] +extern crate objc; +#[macro_use] +extern crate foreign_types; + +use std::borrow::{Borrow, ToOwned}; +use std::marker::PhantomData; +use std::mem; +use std::ops::Deref; +use std::os::raw::c_void; + +use cocoa_foundation::foundation::NSUInteger; +use foreign_types::ForeignType; +use objc::runtime::{Object, BOOL, NO, YES}; + +#[cfg(target_pointer_width = "64")] +pub type CGFloat = f64; +#[cfg(not(target_pointer_width = "64"))] +pub type CGFloat = f32; + +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq)] +pub struct CGSize { + pub width: CGFloat, + pub height: CGFloat, +} + +impl CGSize { + pub fn new(width: f64, height: f64) -> Self { + CGSize { width, height } + } +} + +fn nsstring_as_str(nsstr: &objc::runtime::Object) -> &str { + let bytes = unsafe { + let bytes: *const std::os::raw::c_char = msg_send![nsstr, UTF8String]; + bytes as *const u8 + }; + let len: NSUInteger = unsafe { msg_send![nsstr, length] }; + unsafe { + let bytes = std::slice::from_raw_parts(bytes, len as usize); + std::str::from_utf8(bytes).unwrap() + } +} + +fn nsstring_from_str(string: &str) -> *mut objc::runtime::Object { + const UTF8_ENCODING: usize = 4; + + let cls = class!(NSString); + let bytes = string.as_ptr() as *const c_void; + unsafe { + let obj: *mut objc::runtime::Object = msg_send![cls, alloc]; + let obj: *mut objc::runtime::Object = msg_send![ + obj, + initWithBytes:bytes + length:string.len() + encoding:UTF8_ENCODING + ]; + let _: *mut c_void = msg_send![obj, autorelease]; + obj + } +} + +macro_rules! foreign_obj_type { + {type CType = $raw_ident:ident; + pub struct $owned_ident:ident; + pub struct $ref_ident:ident; + type ParentType = $parent_ref:ident; + } => { + foreign_obj_type! { + type CType = $raw_ident; + pub struct $owned_ident; + pub struct $ref_ident; + } + + impl ::std::ops::Deref for $ref_ident { + type Target = $parent_ref; + + fn deref(&self) -> &$parent_ref { + unsafe { &*(self as *const $ref_ident as *const $parent_ref) } + } + } + }; + {type CType = $raw_ident:ident; + pub struct $owned_ident:ident; + pub struct $ref_ident:ident; + } => { + foreign_type! { + type CType = $raw_ident; + fn drop = crate::obj_drop; + fn clone = crate::obj_clone; + pub struct $owned_ident; + pub struct $ref_ident; + } + + unsafe impl ::objc::Message for $raw_ident { + } + unsafe impl ::objc::Message for $ref_ident { + } + + impl ::std::fmt::Debug for $ref_ident { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + unsafe { + let string: *mut ::objc::runtime::Object = msg_send![self, debugDescription]; + write!(f, "{}", crate::nsstring_as_str(&*string)) + } + } + } + + impl ::std::fmt::Debug for $owned_ident { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + ::std::ops::Deref::deref(self).fmt(f) + } + } + }; +} + +macro_rules! try_objc { + { + $err_name: ident => $body:expr + } => { + { + let mut $err_name: *mut ::objc::runtime::Object = ::std::ptr::null_mut(); + let value = $body; + if !$err_name.is_null() { + let desc: *mut Object = msg_send![$err_name, localizedDescription]; + let compile_error: *const std::os::raw::c_char = msg_send![desc, UTF8String]; + let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned(); + let () = msg_send![$err_name, release]; + return Err(message); + } + value + } + }; +} + +pub struct NSArray<T> { + _phantom: PhantomData<T>, +} + +pub struct Array<T>(*mut NSArray<T>) +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static; +pub struct ArrayRef<T>(foreign_types::Opaque, PhantomData<T>) +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static; + +impl<T> Drop for Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + fn drop(&mut self) { + unsafe { + let () = msg_send![self.0, release]; + } + } +} + +impl<T> Clone for Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + fn clone(&self) -> Self { + unsafe { Array(msg_send![self.0, retain]) } + } +} + +unsafe impl<T> objc::Message for NSArray<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ +} +unsafe impl<T> objc::Message for ArrayRef<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ +} + +impl<T> Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + pub fn from_slice<'a>(s: &[&T::Ref]) -> &'a ArrayRef<T> { + unsafe { + let class = class!(NSArray); + msg_send![class, arrayWithObjects: s.as_ptr() count: s.len()] + } + } + + pub fn from_owned_slice<'a>(s: &[T]) -> &'a ArrayRef<T> { + unsafe { + let class = class!(NSArray); + msg_send![class, arrayWithObjects: s.as_ptr() count: s.len()] + } + } +} + +impl<T> foreign_types::ForeignType for Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + type CType = NSArray<T>; + type Ref = ArrayRef<T>; + + unsafe fn from_ptr(p: *mut NSArray<T>) -> Self { + Array(p) + } + + fn as_ptr(&self) -> *mut NSArray<T> { + self.0 + } +} + +impl<T> foreign_types::ForeignTypeRef for ArrayRef<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + type CType = NSArray<T>; +} + +impl<T> Deref for Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + type Target = ArrayRef<T>; + + fn deref(&self) -> &ArrayRef<T> { + unsafe { mem::transmute(self.as_ptr()) } + } +} + +impl<T> Borrow<ArrayRef<T>> for Array<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + fn borrow(&self) -> &ArrayRef<T> { + unsafe { mem::transmute(self.as_ptr()) } + } +} + +impl<T> ToOwned for ArrayRef<T> +where + T: ForeignType + 'static, + T::Ref: objc::Message + 'static, +{ + type Owned = Array<T>; + + fn to_owned(&self) -> Array<T> { + unsafe { Array::from_ptr(msg_send![self, retain]) } + } +} + +pub enum CAMetalDrawable {} + +foreign_obj_type! { + type CType = CAMetalDrawable; + pub struct CoreAnimationDrawable; + pub struct CoreAnimationDrawableRef; + type ParentType = DrawableRef; +} + +impl CoreAnimationDrawableRef { + pub fn texture(&self) -> &TextureRef { + unsafe { msg_send![self, texture] } + } +} + +pub enum CAMetalLayer {} + +foreign_obj_type! { + type CType = CAMetalLayer; + pub struct CoreAnimationLayer; + pub struct CoreAnimationLayerRef; +} + +impl CoreAnimationLayer { + pub fn new() -> Self { + unsafe { + let class = class!(CAMetalLayer); + msg_send![class, new] + } + } +} + +impl CoreAnimationLayerRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } + + pub fn set_device(&self, device: &DeviceRef) { + unsafe { msg_send![self, setDevice: device] } + } + + pub fn pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, pixelFormat] } + } + + pub fn set_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setPixelFormat: pixel_format] } + } + + pub fn drawable_size(&self) -> CGSize { + unsafe { msg_send![self, drawableSize] } + } + + pub fn set_drawable_size(&self, size: CGSize) { + unsafe { msg_send![self, setDrawableSize: size] } + } + + pub fn presents_with_transaction(&self) -> bool { + unsafe { + match msg_send![self, presentsWithTransaction] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_presents_with_transaction(&self, transaction: bool) { + unsafe { msg_send![self, setPresentsWithTransaction: transaction] } + } + + pub fn set_edge_antialiasing_mask(&self, mask: u64) { + unsafe { msg_send![self, setEdgeAntialiasingMask: mask] } + } + + pub fn set_masks_to_bounds(&self, masks: bool) { + unsafe { msg_send![self, setMasksToBounds: masks] } + } + + pub fn remove_all_animations(&self) { + unsafe { msg_send![self, removeAllAnimations] } + } + + pub fn next_drawable(&self) -> Option<&CoreAnimationDrawableRef> { + unsafe { msg_send![self, nextDrawable] } + } + + pub fn set_contents_scale(&self, scale: CGFloat) { + unsafe { msg_send![self, setContentsScale: scale] } + } + + /// [framebufferOnly Apple Docs](https://developer.apple.com/documentation/metal/mtltexture/1515749-framebufferonly?language=objc) + pub fn set_framebuffer_only(&self, framebuffer_only: BOOL) { + unsafe { msg_send![self, setFramebufferOnly: framebuffer_only] } + } +} + +mod argument; +mod buffer; +mod capturedescriptor; +mod capturemanager; +mod commandbuffer; +mod commandqueue; +mod constants; +mod depthstencil; +mod device; +mod drawable; +mod encoder; +mod heap; +mod indirect_encoder; +mod library; +mod pipeline; +mod renderpass; +mod resource; +mod sampler; +mod texture; +mod types; +mod vertexdescriptor; + +#[rustfmt::skip] +pub use { + argument::*, + buffer::*, + capturedescriptor::*, + capturemanager::*, + commandbuffer::*, + commandqueue::*, + constants::*, + depthstencil::*, + device::*, + drawable::*, + encoder::*, + heap::*, + indirect_encoder::*, + library::*, + pipeline::*, + renderpass::*, + resource::*, + sampler::*, + texture::*, + types::*, + vertexdescriptor::*, +}; + +#[inline] +unsafe fn obj_drop<T>(p: *mut T) { + msg_send![(p as *mut Object), release] +} + +#[inline] +unsafe fn obj_clone<T: 'static>(p: *mut T) -> *mut T { + msg_send![(p as *mut Object), retain] +} + +#[allow(non_camel_case_types)] +type c_size_t = usize; diff --git a/third_party/rust/metal/src/library.rs b/third_party/rust/metal/src/library.rs new file mode 100644 index 0000000000..6a8df76bb0 --- /dev/null +++ b/third_party/rust/metal/src/library.rs @@ -0,0 +1,259 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSUInteger; +use foreign_types::ForeignType; +use objc::runtime::{Object, NO, YES}; +use std::ffi::CStr; + +pub enum MTLVertexAttribute {} + +foreign_obj_type! { + type CType = MTLVertexAttribute; + pub struct VertexAttribute; + pub struct VertexAttributeRef; +} + +impl VertexAttributeRef { + pub fn name(&self) -> &str { + unsafe { + let name = msg_send![self, name]; + crate::nsstring_as_str(name) + } + } + + pub fn attribute_index(&self) -> u64 { + unsafe { msg_send![self, attributeIndex] } + } + + pub fn attribute_type(&self) -> MTLDataType { + unsafe { msg_send![self, attributeType] } + } + + pub fn is_active(&self) -> bool { + unsafe { + match msg_send![self, isActive] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLFunctionType { + Vertex = 1, + Fragment = 2, + Kernel = 3, +} + +pub enum MTLFunction {} + +foreign_obj_type! { + type CType = MTLFunction; + pub struct Function; + pub struct FunctionRef; +} + +impl FunctionRef { + pub fn name(&self) -> &str { + unsafe { + let name = msg_send![self, name]; + crate::nsstring_as_str(name) + } + } + + pub fn function_type(&self) -> MTLFunctionType { + unsafe { msg_send![self, functionType] } + } + + pub fn vertex_attributes(&self) -> &Array<VertexAttribute> { + unsafe { msg_send![self, vertexAttributes] } + } + + pub fn new_argument_encoder(&self, buffer_index: NSUInteger) -> ArgumentEncoder { + unsafe { + let ptr = msg_send![self, newArgumentEncoderWithBufferIndex: buffer_index]; + ArgumentEncoder::from_ptr(ptr) + } + } + + pub fn function_constants_dictionary(&self) -> *mut Object { + unsafe { msg_send![self, functionConstantsDictionary] } + } +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] +pub enum MTLLanguageVersion { + V1_0 = 0x10000, + V1_1 = 0x10001, + V1_2 = 0x10002, + V2_0 = 0x20000, + V2_1 = 0x20001, + V2_2 = 0x20002, +} + +pub enum MTLFunctionConstantValues {} + +foreign_obj_type! { + type CType = MTLFunctionConstantValues; + pub struct FunctionConstantValues; + pub struct FunctionConstantValuesRef; +} + +impl FunctionConstantValues { + pub fn new() -> Self { + unsafe { + let class = class!(MTLFunctionConstantValues); + msg_send![class, new] + } + } +} + +impl FunctionConstantValuesRef { + pub unsafe fn set_constant_value_at_index( + &self, + index: NSUInteger, + ty: MTLDataType, + value: *const std::os::raw::c_void, + ) { + msg_send![self, setConstantValue:value type:ty atIndex:index] + } +} + +pub enum MTLCompileOptions {} + +foreign_obj_type! { + type CType = MTLCompileOptions; + pub struct CompileOptions; + pub struct CompileOptionsRef; +} + +impl CompileOptions { + pub fn new() -> Self { + unsafe { + let class = class!(MTLCompileOptions); + msg_send![class, new] + } + } +} + +impl CompileOptionsRef { + pub unsafe fn preprocessor_defines(&self) -> *mut Object { + msg_send![self, preprocessorMacros] + } + + pub unsafe fn set_preprocessor_defines(&self, defines: *mut Object) { + msg_send![self, setPreprocessorMacros: defines] + } + + pub fn is_fast_math_enabled(&self) -> bool { + unsafe { + match msg_send![self, fastMathEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_fast_math_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setFastMathEnabled: enabled] } + } + + pub fn language_version(&self) -> MTLLanguageVersion { + unsafe { msg_send![self, languageVersion] } + } + + pub fn set_language_version(&self, version: MTLLanguageVersion) { + unsafe { msg_send![self, setLanguageVersion: version] } + } +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLLibraryError { + Unsupported = 1, + Internal = 2, + CompileFailure = 3, + CompileWarning = 4, +} + +pub enum MTLLibrary {} + +foreign_obj_type! { + type CType = MTLLibrary; + pub struct Library; + pub struct LibraryRef; +} + +impl LibraryRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } + + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn get_function( + &self, + name: &str, + constants: Option<FunctionConstantValues>, + ) -> Result<Function, String> { + unsafe { + let nsname = crate::nsstring_from_str(name); + + let function: *mut MTLFunction = match constants { + Some(c) => try_objc! { err => msg_send![self, + newFunctionWithName: nsname.as_ref() + constantValues: c.as_ref() + error: &mut err + ]}, + None => msg_send![self, newFunctionWithName: nsname.as_ref()], + }; + + if !function.is_null() { + Ok(Function::from_ptr(function)) + } else { + Err(format!("Function '{}' does not exist", name)) + } + } + } + + pub fn function_names(&self) -> Vec<String> { + unsafe { + let names: *mut Object = msg_send![self, functionNames]; + let count: NSUInteger = msg_send![names, count]; + let ret = (0..count) + .map(|i| { + let name = msg_send![names, objectAtIndex: i]; + nsstring_as_str(name).to_string() + }) + .collect(); + let () = msg_send![names, release]; + ret + } + } +} diff --git a/third_party/rust/metal/src/pipeline/compute.rs b/third_party/rust/metal/src/pipeline/compute.rs new file mode 100644 index 0000000000..67724b1c9c --- /dev/null +++ b/third_party/rust/metal/src/pipeline/compute.rs @@ -0,0 +1,354 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSUInteger; +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLAttributeFormat { + Invalid = 0, + UChar2 = 1, + UChar3 = 2, + UChar4 = 3, + Char2 = 4, + Char3 = 5, + Char4 = 6, + UChar2Normalized = 7, + UChar3Normalized = 8, + UChar4Normalized = 9, + Char2Normalized = 10, + Char3Normalized = 11, + Char4Normalized = 12, + UShort2 = 13, + UShort3 = 14, + UShort4 = 15, + Short2 = 16, + Short3 = 17, + Short4 = 18, + UShort2Normalized = 19, + UShort3Normalized = 20, + UShort4Normalized = 21, + Short2Normalized = 22, + Short3Normalized = 23, + Short4Normalized = 24, + Half2 = 25, + Half3 = 26, + Half4 = 27, + Float = 28, + Float2 = 29, + Float3 = 30, + Float4 = 31, + Int = 32, + Int2 = 33, + Int3 = 34, + Int4 = 35, + UInt = 36, + UInt2 = 37, + UInt3 = 38, + UInt4 = 39, + Int1010102Normalized = 40, + UInt1010102Normalized = 41, + UChar4Normalized_BGRA = 42, + UChar = 45, + Char = 46, + UCharNormalized = 47, + CharNormalized = 48, + UShort = 49, + Short = 50, + UShortNormalized = 51, + ShortNormalized = 52, + Half = 53, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLStepFunction { + Constant = 0, + PerInstance = 1, + PerPatch = 2, + PerPatchControlPoint = 3, + PerVertex = 4, + ThreadPositionInGridX = 5, + ThreadPositionInGridXIndexed = 6, + ThreadPositionInGridY = 7, + ThreadPositionInGridYIndexed = 8, +} + +pub enum MTLComputePipelineDescriptor {} + +foreign_obj_type! { + type CType = MTLComputePipelineDescriptor; + pub struct ComputePipelineDescriptor; + pub struct ComputePipelineDescriptorRef; +} + +impl ComputePipelineDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLComputePipelineDescriptor); + msg_send![class, new] + } + } +} + +impl ComputePipelineDescriptorRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn compute_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, computeFunction] } + } + + pub fn set_compute_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setComputeFunction: function] } + } + + pub fn thread_group_size_is_multiple_of_thread_execution_width(&self) -> bool { + unsafe { + match msg_send![self, threadGroupSizeIsMultipleOfThreadExecutionWidth] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_thread_group_size_is_multiple_of_thread_execution_width( + &self, + size_is_multiple_of_width: bool, + ) { + unsafe { + msg_send![ + self, + setThreadGroupSizeIsMultipleOfThreadExecutionWidth: size_is_multiple_of_width + ] + } + } + + pub fn stage_input_descriptor(&self) -> Option<&StageInputOutputDescriptorRef> { + unsafe { msg_send![self, stageInputDescriptor] } + } + + pub fn set_stage_input_descriptor(&self, descriptor: Option<&StageInputOutputDescriptorRef>) { + unsafe { msg_send![self, setStageInputDescriptor: descriptor] } + } + + pub fn buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, buffers] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLComputePipelineState {} + +foreign_obj_type! { + type CType = MTLComputePipelineState; + pub struct ComputePipelineState; + pub struct ComputePipelineStateRef; +} + +impl ComputePipelineStateRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn max_total_threads_per_group(&self) -> NSUInteger { + unsafe { msg_send![self, maxTotalThreadsPerThreadgroup] } + } + + pub fn thread_execution_width(&self) -> NSUInteger { + unsafe { msg_send![self, threadExecutionWidth] } + } + + pub fn static_threadgroup_memory_length(&self) -> NSUInteger { + unsafe { msg_send![self, staticThreadgroupMemoryLength] } + } +} + +pub enum MTLStageInputOutputDescriptor {} + +foreign_obj_type! { + type CType = MTLStageInputOutputDescriptor; + pub struct StageInputOutputDescriptor; + pub struct StageInputOutputDescriptorRef; +} + +impl StageInputOutputDescriptor { + pub fn new<'a>() -> &'a StageInputOutputDescriptorRef { + unsafe { + let class = class!(MTLStageInputOutputDescriptor); + msg_send![class, stageInputOutputDescriptor] + } + } +} + +impl StageInputOutputDescriptorRef { + pub fn attributes(&self) -> Option<&AttributeDescriptorArrayRef> { + unsafe { msg_send![self, attributes] } + } + + pub fn index_buffer_index(&self) -> NSUInteger { + unsafe { msg_send![self, indexBufferIndex] } + } + + pub fn set_index_buffer_index(&self, idx_buffer_idx: NSUInteger) { + unsafe { msg_send![self, setIndexBufferIndex: idx_buffer_idx] } + } + + pub fn index_type(&self) -> MTLIndexType { + unsafe { msg_send![self, indexType] } + } + + pub fn set_index_type(&self, index_ty: MTLIndexType) { + unsafe { msg_send![self, setIndexType: index_ty] } + } + + pub fn layouts(&self) -> Option<&BufferLayoutDescriptorArrayRef> { + unsafe { msg_send![self, layouts] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLAttributeDescriptorArray {} + +foreign_obj_type! { + type CType = MTLAttributeDescriptorArray; + pub struct AttributeDescriptorArray; + pub struct AttributeDescriptorArrayRef; +} + +impl AttributeDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&AttributeDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at(&self, index: NSUInteger, buffer_desc: Option<&AttributeDescriptorRef>) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLAttributeDescriptor {} + +foreign_obj_type! { + type CType = MTLAttributeDescriptor; + pub struct AttributeDescriptor; + pub struct AttributeDescriptorRef; +} + +impl AttributeDescriptorRef { + pub fn buffer_index(&self) -> NSUInteger { + unsafe { msg_send![self, bufferIndex] } + } + + pub fn set_buffer_index(&self, buffer_index: NSUInteger) { + unsafe { msg_send![self, setBufferIndex: buffer_index] } + } + + pub fn format(&self) -> MTLAttributeFormat { + unsafe { msg_send![self, format] } + } + + pub fn set_format(&self, format: MTLAttributeFormat) { + unsafe { msg_send![self, setFormat: format] } + } + + pub fn offset(&self) -> NSUInteger { + unsafe { msg_send![self, offset] } + } + + pub fn set_offset(&self, offset: NSUInteger) { + unsafe { msg_send![self, setOffset: offset] } + } +} + +pub enum MTLBufferLayoutDescriptorArray {} + +foreign_obj_type! { + type CType = MTLBufferLayoutDescriptorArray; + pub struct BufferLayoutDescriptorArray; + pub struct BufferLayoutDescriptorArrayRef; +} + +impl BufferLayoutDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&BufferLayoutDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + buffer_desc: Option<&BufferLayoutDescriptorRef>, + ) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLBufferLayoutDescriptor {} + +foreign_obj_type! { + type CType = MTLBufferLayoutDescriptor; + pub struct BufferLayoutDescriptor; + pub struct BufferLayoutDescriptorRef; +} + +impl BufferLayoutDescriptorRef { + pub fn step_function(&self) -> MTLStepFunction { + unsafe { msg_send![self, stepFunction] } + } + + pub fn set_step_function(&self, step_function: MTLStepFunction) { + unsafe { msg_send![self, setStepFunction: step_function] } + } + + pub fn step_rate(&self) -> NSUInteger { + unsafe { msg_send![self, stepRate] } + } + + pub fn set_step_rate(&self, step_rate: NSUInteger) { + unsafe { msg_send![self, setStepRate: step_rate] } + } + + pub fn stride(&self) -> NSUInteger { + unsafe { msg_send![self, stride] } + } + + pub fn set_stride(&self, stride: NSUInteger) { + unsafe { msg_send![self, setStride: stride] } + } +} diff --git a/third_party/rust/metal/src/pipeline/mod.rs b/third_party/rust/metal/src/pipeline/mod.rs new file mode 100644 index 0000000000..e65d28d6ca --- /dev/null +++ b/third_party/rust/metal/src/pipeline/mod.rs @@ -0,0 +1,70 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +mod compute; +mod render; + +pub use self::compute::*; +pub use self::render::*; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLMutability { + Default = 0, + Mutable = 1, + Immutable = 2, +} + +impl Default for MTLMutability { + #[inline] + fn default() -> Self { + MTLMutability::Default + } +} + +pub enum MTLPipelineBufferDescriptorArray {} + +foreign_obj_type! { + type CType = MTLPipelineBufferDescriptorArray; + pub struct PipelineBufferDescriptorArray; + pub struct PipelineBufferDescriptorArrayRef; +} + +impl PipelineBufferDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&PipelineBufferDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + buffer_desc: Option<&PipelineBufferDescriptorRef>, + ) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLPipelineBufferDescriptor {} + +foreign_obj_type! { + type CType = MTLPipelineBufferDescriptor; + pub struct PipelineBufferDescriptor; + pub struct PipelineBufferDescriptorRef; +} + +impl PipelineBufferDescriptorRef { + pub fn mutability(&self) -> MTLMutability { + unsafe { msg_send![self, mutability] } + } + + pub fn set_mutability(&self, new_mutability: MTLMutability) { + unsafe { msg_send![self, setMutability: new_mutability] } + } +} diff --git a/third_party/rust/metal/src/pipeline/render.rs b/third_party/rust/metal/src/pipeline/render.rs new file mode 100644 index 0000000000..6a4f91b2a4 --- /dev/null +++ b/third_party/rust/metal/src/pipeline/render.rs @@ -0,0 +1,432 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSUInteger; +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLBlendFactor { + Zero = 0, + One = 1, + SourceColor = 2, + OneMinusSourceColor = 3, + SourceAlpha = 4, + OneMinusSourceAlpha = 5, + DestinationColor = 6, + OneMinusDestinationColor = 7, + DestinationAlpha = 8, + OneMinusDestinationAlpha = 9, + SourceAlphaSaturated = 10, + BlendColor = 11, + OneMinusBlendColor = 12, + BlendAlpha = 13, + OneMinusBlendAlpha = 14, + Source1Color = 15, + OneMinusSource1Color = 16, + Source1Alpha = 17, + OneMinusSource1Alpha = 18, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLBlendOperation { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, +} + +bitflags! { + pub struct MTLColorWriteMask: NSUInteger { + const Red = 0x1 << 3; + const Green = 0x1 << 2; + const Blue = 0x1 << 1; + const Alpha = 0x1 << 0; + } +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLPrimitiveTopologyClass { + Unspecified = 0, + Point = 1, + Line = 2, + Triangle = 3, +} + +pub enum MTLRenderPipelineColorAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPipelineColorAttachmentDescriptor; + pub struct RenderPipelineColorAttachmentDescriptor; + pub struct RenderPipelineColorAttachmentDescriptorRef; +} + +impl RenderPipelineColorAttachmentDescriptorRef { + pub fn pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, pixelFormat] } + } + + pub fn set_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setPixelFormat: pixel_format] } + } + + pub fn is_blending_enabled(&self) -> bool { + unsafe { + match msg_send![self, isBlendingEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_blending_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setBlendingEnabled: enabled] } + } + + pub fn source_rgb_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, sourceRGBBlendFactor] } + } + + pub fn set_source_rgb_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setSourceRGBBlendFactor: blend_factor] } + } + + pub fn destination_rgb_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, destinationRGBBlendFactor] } + } + + pub fn set_destination_rgb_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setDestinationRGBBlendFactor: blend_factor] } + } + + pub fn rgb_blend_operation(&self) -> MTLBlendOperation { + unsafe { msg_send![self, rgbBlendOperation] } + } + + pub fn set_rgb_blend_operation(&self, blend_operation: MTLBlendOperation) { + unsafe { msg_send![self, setRgbBlendOperation: blend_operation] } + } + + pub fn source_alpha_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, sourceAlphaBlendFactor] } + } + + pub fn set_source_alpha_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setSourceAlphaBlendFactor: blend_factor] } + } + + pub fn destination_alpha_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, destinationAlphaBlendFactor] } + } + + pub fn set_destination_alpha_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setDestinationAlphaBlendFactor: blend_factor] } + } + + pub fn alpha_blend_operation(&self) -> MTLBlendOperation { + unsafe { msg_send![self, alphaBlendOperation] } + } + + pub fn set_alpha_blend_operation(&self, blend_operation: MTLBlendOperation) { + unsafe { msg_send![self, setAlphaBlendOperation: blend_operation] } + } + + pub fn write_mask(&self) -> MTLColorWriteMask { + unsafe { msg_send![self, writeMask] } + } + + pub fn set_write_mask(&self, mask: MTLColorWriteMask) { + unsafe { msg_send![self, setWriteMask: mask] } + } +} + +pub enum MTLRenderPipelineReflection {} + +foreign_obj_type! { + type CType = MTLRenderPipelineReflection; + pub struct RenderPipelineReflection; + pub struct RenderPipelineReflectionRef; +} + +impl RenderPipelineReflection { + #[cfg(feature = "private")] + pub unsafe fn new( + vertex_data: *mut std::ffi::c_void, + fragment_data: *mut std::ffi::c_void, + vertex_desc: *mut std::ffi::c_void, + device: &DeviceRef, + options: u64, + flags: u64, + ) -> Self { + let class = class!(MTLRenderPipelineReflection); + let this: RenderPipelineReflection = msg_send![class, alloc]; + let this_alias: *mut Object = msg_send![this.as_ref(), initWithVertexData:vertex_data + fragmentData:fragment_data + serializedVertexDescriptor:vertex_desc + device:device + options:options + flags:flags]; + if this_alias.is_null() { + panic!("[MTLRenderPipelineReflection init] failed"); + } + this + } +} + +impl RenderPipelineReflectionRef { + pub fn fragment_arguments(&self) -> &Array<Argument> { + unsafe { msg_send![self, fragmentArguments] } + } + + pub fn vertex_arguments(&self) -> &Array<Argument> { + unsafe { msg_send![self, vertexArguments] } + } +} + +pub enum MTLRenderPipelineDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPipelineDescriptor; + pub struct RenderPipelineDescriptor; + pub struct RenderPipelineDescriptorRef; +} + +impl RenderPipelineDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLRenderPipelineDescriptor); + msg_send![class, new] + } + } +} + +impl RenderPipelineDescriptorRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn vertex_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, vertexFunction] } + } + + pub fn set_vertex_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setVertexFunction: function] } + } + + pub fn fragment_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, fragmentFunction] } + } + + pub fn set_fragment_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setFragmentFunction: function] } + } + + pub fn vertex_descriptor(&self) -> Option<&VertexDescriptorRef> { + unsafe { msg_send![self, vertexDescriptor] } + } + + pub fn set_vertex_descriptor(&self, descriptor: Option<&VertexDescriptorRef>) { + unsafe { msg_send![self, setVertexDescriptor: descriptor] } + } + + pub fn sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, sampleCount] } + } + + pub fn set_sample_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setSampleCount: count] } + } + + pub fn max_vertex_amplification_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxVertexAmplificationCount] } + } + + pub fn set_max_vertex_amplification_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMaxVertexAmplificationCount: count] } + } + + pub fn is_alpha_to_coverage_enabled(&self) -> bool { + unsafe { + match msg_send![self, isAlphaToCoverageEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_alpha_to_coverage_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setAlphaToCoverageEnabled: enabled] } + } + + pub fn is_alpha_to_one_enabled(&self) -> bool { + unsafe { + match msg_send![self, isAlphaToOneEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_alpha_to_one_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setAlphaToOneEnabled: enabled] } + } + + pub fn is_rasterization_enabled(&self) -> bool { + unsafe { + match msg_send![self, isRasterizationEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_rasterization_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setRasterizationEnabled: enabled] } + } + + pub fn color_attachments(&self) -> &RenderPipelineColorAttachmentDescriptorArrayRef { + unsafe { msg_send![self, colorAttachments] } + } + + pub fn depth_attachment_pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, depthAttachmentPixelFormat] } + } + + pub fn set_depth_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setDepthAttachmentPixelFormat: pixel_format] } + } + + pub fn stencil_attachment_pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, stencilAttachmentPixelFormat] } + } + + pub fn set_stencil_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setStencilAttachmentPixelFormat: pixel_format] } + } + + pub fn input_primitive_topology(&self) -> MTLPrimitiveTopologyClass { + unsafe { msg_send![self, inputPrimitiveTopology] } + } + + pub fn set_input_primitive_topology(&self, topology: MTLPrimitiveTopologyClass) { + unsafe { msg_send![self, setInputPrimitiveTopology: topology] } + } + + #[cfg(feature = "private")] + pub unsafe fn serialize_vertex_data(&self) -> *mut std::ffi::c_void { + use std::ptr; + let flags = 0; + let err: *mut Object = ptr::null_mut(); + msg_send![self, newSerializedVertexDataWithFlags:flags + error:err] + } + + #[cfg(feature = "private")] + pub unsafe fn serialize_fragment_data(&self) -> *mut std::ffi::c_void { + msg_send![self, serializeFragmentData] + } + + pub fn support_indirect_command_buffers(&self) -> bool { + unsafe { + match msg_send![self, supportIndirectCommandBuffers] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_support_indirect_command_buffers(&self, support: bool) { + unsafe { msg_send![self, setSupportIndirectCommandBuffers: support] } + } + + pub fn vertex_buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, vertexBuffers] } + } + + pub fn fragment_buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, fragmentBuffers] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLRenderPipelineState {} + +foreign_obj_type! { + type CType = MTLRenderPipelineState; + pub struct RenderPipelineState; + pub struct RenderPipelineStateRef; +} + +impl RenderPipelineStateRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } +} + +pub enum MTLRenderPipelineColorAttachmentDescriptorArray {} + +foreign_obj_type! { + type CType = MTLRenderPipelineColorAttachmentDescriptorArray; + pub struct RenderPipelineColorAttachmentDescriptorArray; + pub struct RenderPipelineColorAttachmentDescriptorArrayRef; +} + +impl RenderPipelineColorAttachmentDescriptorArrayRef { + pub fn object_at( + &self, + index: NSUInteger, + ) -> Option<&RenderPipelineColorAttachmentDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + attachment: Option<&RenderPipelineColorAttachmentDescriptorRef>, + ) { + unsafe { + msg_send![self, setObject:attachment + atIndexedSubscript:index] + } + } +} diff --git a/third_party/rust/metal/src/renderpass.rs b/third_party/rust/metal/src/renderpass.rs new file mode 100644 index 0000000000..4d1e867eb7 --- /dev/null +++ b/third_party/rust/metal/src/renderpass.rs @@ -0,0 +1,334 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::NSUInteger; + +#[repr(u64)] +#[derive(Copy, Clone, Debug)] +pub enum MTLLoadAction { + DontCare = 0, + Load = 1, + Clear = 2, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug)] +pub enum MTLStoreAction { + DontCare = 0, + Store = 1, + MultisampleResolve = 2, + StoreAndMultisampleResolve = 3, + Unknown = 4, + CustomSampleDepthStore = 5, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLClearColor { + pub red: f64, + pub green: f64, + pub blue: f64, + pub alpha: f64, +} + +impl MTLClearColor { + #[inline] + pub fn new(red: f64, green: f64, blue: f64, alpha: f64) -> Self { + Self { + red, + green, + blue, + alpha, + } + } +} + +#[repr(u32)] +#[allow(non_camel_case_types)] +pub enum MTLMultisampleStencilResolveFilter { + Sample0 = 0, + DepthResolvedSample = 1, +} + +pub enum MTLRenderPassAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPassAttachmentDescriptor; + pub struct RenderPassAttachmentDescriptor; + pub struct RenderPassAttachmentDescriptorRef; +} + +impl RenderPassAttachmentDescriptorRef { + pub fn texture(&self) -> Option<&TextureRef> { + unsafe { msg_send![self, texture] } + } + + pub fn set_texture(&self, texture: Option<&TextureRef>) { + unsafe { msg_send![self, setTexture: texture] } + } + + pub fn level(&self) -> NSUInteger { + unsafe { msg_send![self, level] } + } + + pub fn set_level(&self, level: NSUInteger) { + unsafe { msg_send![self, setLevel: level] } + } + + pub fn slice(&self) -> NSUInteger { + unsafe { msg_send![self, slice] } + } + + pub fn set_slice(&self, slice: NSUInteger) { + unsafe { msg_send![self, setSlice: slice] } + } + + pub fn depth_plane(&self) -> NSUInteger { + unsafe { msg_send![self, depthPlane] } + } + + pub fn set_depth_plane(&self, depth_plane: NSUInteger) { + unsafe { msg_send![self, setDepthPlane: depth_plane] } + } + + pub fn resolve_texture(&self) -> Option<&TextureRef> { + unsafe { msg_send![self, resolveTexture] } + } + + pub fn set_resolve_texture(&self, resolve_texture: Option<&TextureRef>) { + unsafe { msg_send![self, setResolveTexture: resolve_texture] } + } + + pub fn resolve_level(&self) -> NSUInteger { + unsafe { msg_send![self, resolveLevel] } + } + + pub fn set_resolve_level(&self, resolve_level: NSUInteger) { + unsafe { msg_send![self, setResolveLevel: resolve_level] } + } + + pub fn resolve_slice(&self) -> NSUInteger { + unsafe { msg_send![self, resolveSlice] } + } + + pub fn set_resolve_slice(&self, resolve_slice: NSUInteger) { + unsafe { msg_send![self, setResolveSlice: resolve_slice] } + } + + pub fn resolve_depth_plane(&self) -> NSUInteger { + unsafe { msg_send![self, resolveDepthPlane] } + } + + pub fn set_resolve_depth_plane(&self, resolve_depth_plane: NSUInteger) { + unsafe { msg_send![self, setResolveDepthPlane: resolve_depth_plane] } + } + + pub fn load_action(&self) -> MTLLoadAction { + unsafe { msg_send![self, loadAction] } + } + + pub fn set_load_action(&self, load_action: MTLLoadAction) { + unsafe { msg_send![self, setLoadAction: load_action] } + } + + pub fn store_action(&self) -> MTLStoreAction { + unsafe { msg_send![self, storeAction] } + } + + pub fn set_store_action(&self, store_action: MTLStoreAction) { + unsafe { msg_send![self, setStoreAction: store_action] } + } +} + +pub enum MTLRenderPassColorAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPassColorAttachmentDescriptor; + pub struct RenderPassColorAttachmentDescriptor; + pub struct RenderPassColorAttachmentDescriptorRef; + type ParentType = RenderPassAttachmentDescriptorRef; +} + +impl RenderPassColorAttachmentDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLRenderPassColorAttachmentDescriptor); + msg_send![class, new] + } + } +} + +impl RenderPassColorAttachmentDescriptorRef { + pub fn clear_color(&self) -> MTLClearColor { + unsafe { msg_send![self, clearColor] } + } + + pub fn set_clear_color(&self, clear_color: MTLClearColor) { + unsafe { msg_send![self, setClearColor: clear_color] } + } +} + +pub enum MTLRenderPassDepthAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPassDepthAttachmentDescriptor; + pub struct RenderPassDepthAttachmentDescriptor; + pub struct RenderPassDepthAttachmentDescriptorRef; + type ParentType = RenderPassAttachmentDescriptorRef; +} + +impl RenderPassDepthAttachmentDescriptorRef { + pub fn clear_depth(&self) -> f64 { + unsafe { msg_send![self, clearDepth] } + } + + pub fn set_clear_depth(&self, clear_depth: f64) { + unsafe { msg_send![self, setClearDepth: clear_depth] } + } +} + +pub enum MTLRenderPassStencilAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPassStencilAttachmentDescriptor; + pub struct RenderPassStencilAttachmentDescriptor; + pub struct RenderPassStencilAttachmentDescriptorRef; + type ParentType = RenderPassAttachmentDescriptorRef; +} + +impl RenderPassStencilAttachmentDescriptorRef { + pub fn clear_stencil(&self) -> u32 { + unsafe { msg_send![self, clearStencil] } + } + + pub fn set_clear_stencil(&self, clear_stencil: u32) { + unsafe { msg_send![self, setClearStencil: clear_stencil] } + } + + pub fn stencil_resolve_filter(&self) -> MTLMultisampleStencilResolveFilter { + unsafe { msg_send![self, stencilResolveFilter] } + } + + pub fn set_stencil_resolve_filter( + &self, + stencil_resolve_filter: MTLMultisampleStencilResolveFilter, + ) { + unsafe { msg_send![self, setStencilResolveFilter: stencil_resolve_filter] } + } +} + +pub enum MTLRenderPassColorAttachmentDescriptorArray {} + +foreign_obj_type! { + type CType = MTLRenderPassColorAttachmentDescriptorArray; + pub struct RenderPassColorAttachmentDescriptorArray; + pub struct RenderPassColorAttachmentDescriptorArrayRef; +} + +impl RenderPassColorAttachmentDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&RenderPassColorAttachmentDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + attachment: Option<&RenderPassColorAttachmentDescriptorRef>, + ) { + unsafe { + msg_send![self, setObject:attachment + atIndexedSubscript:index] + } + } +} + +pub enum MTLRenderPassDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPassDescriptor; + pub struct RenderPassDescriptor; + pub struct RenderPassDescriptorRef; +} + +impl RenderPassDescriptor { + pub fn new<'a>() -> &'a RenderPassDescriptorRef { + unsafe { + let class = class!(MTLRenderPassDescriptorInternal); + msg_send![class, renderPassDescriptor] + } + } +} + +impl RenderPassDescriptorRef { + pub fn color_attachments(&self) -> &RenderPassColorAttachmentDescriptorArrayRef { + unsafe { msg_send![self, colorAttachments] } + } + + pub fn depth_attachment(&self) -> Option<&RenderPassDepthAttachmentDescriptorRef> { + unsafe { msg_send![self, depthAttachment] } + } + + pub fn set_depth_attachment( + &self, + depth_attachment: Option<&RenderPassDepthAttachmentDescriptorRef>, + ) { + unsafe { msg_send![self, setDepthAttachment: depth_attachment] } + } + + pub fn stencil_attachment(&self) -> Option<&RenderPassStencilAttachmentDescriptorRef> { + unsafe { msg_send![self, stencilAttachment] } + } + + pub fn set_stencil_attachment( + &self, + stencil_attachment: Option<&RenderPassStencilAttachmentDescriptorRef>, + ) { + unsafe { msg_send![self, setStencilAttachment: stencil_attachment] } + } + + pub fn visibility_result_buffer(&self) -> Option<&BufferRef> { + unsafe { msg_send![self, visibilityResultBuffer] } + } + + pub fn set_visibility_result_buffer(&self, buffer: Option<&BufferRef>) { + unsafe { msg_send![self, setVisibilityResultBuffer: buffer] } + } + + pub fn render_target_array_length(&self) -> NSUInteger { + unsafe { msg_send![self, renderTargetArrayLength] } + } + + pub fn set_render_target_array_length(&self, length: NSUInteger) { + unsafe { msg_send![self, setRenderTargetArrayLength: length] } + } + + pub fn render_target_width(&self) -> NSUInteger { + unsafe { msg_send![self, renderTargetWidth] } + } + + pub fn set_render_target_width(&self, size: NSUInteger) { + unsafe { msg_send![self, setRenderTargetWidth: size] } + } + + pub fn render_target_height(&self) -> NSUInteger { + unsafe { msg_send![self, renderTargetHeight] } + } + + pub fn set_render_target_height(&self, size: NSUInteger) { + unsafe { msg_send![self, setRenderTargetHeight: size] } + } + + pub fn default_raster_sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, defaultRasterSampleCount] } + } + + pub fn set_default_raster_sample_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setDefaultRasterSampleCount: count] } + } +} diff --git a/third_party/rust/metal/src/resource.rs b/third_party/rust/metal/src/resource.rs new file mode 100644 index 0000000000..07974b4225 --- /dev/null +++ b/third_party/rust/metal/src/resource.rs @@ -0,0 +1,115 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::DeviceRef; +use cocoa_foundation::foundation::NSUInteger; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLPurgeableState { + KeepCurrent = 1, + NonVolatile = 2, + Volatile = 3, + Empty = 4, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLCPUCacheMode { + DefaultCache = 0, + WriteCombined = 1, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLStorageMode { + Shared = 0, + Managed = 1, + Private = 2, + Memoryless = 3, +} + +pub const MTLResourceCPUCacheModeShift: NSUInteger = 0; +pub const MTLResourceCPUCacheModeMask: NSUInteger = 0xf << MTLResourceCPUCacheModeShift; +pub const MTLResourceStorageModeShift: NSUInteger = 4; +pub const MTLResourceStorageModeMask: NSUInteger = 0xf << MTLResourceStorageModeShift; + +bitflags! { + #[allow(non_upper_case_globals)] + pub struct MTLResourceOptions: NSUInteger { + const CPUCacheModeDefaultCache = (MTLCPUCacheMode::DefaultCache as NSUInteger) << MTLResourceCPUCacheModeShift; + const CPUCacheModeWriteCombined = (MTLCPUCacheMode::WriteCombined as NSUInteger) << MTLResourceCPUCacheModeShift; + + const StorageModeShared = (MTLStorageMode::Shared as NSUInteger) << MTLResourceStorageModeShift; + const StorageModeManaged = (MTLStorageMode::Managed as NSUInteger) << MTLResourceStorageModeShift; + const StorageModePrivate = (MTLStorageMode::Private as NSUInteger) << MTLResourceStorageModeShift; + const StorageModeMemoryless = (MTLStorageMode::Memoryless as NSUInteger) << MTLResourceStorageModeShift; + } +} + +bitflags! { + pub struct MTLResourceUsage: NSUInteger { + const Read = 1 << 0; + const Write = 1 << 1; + const Sample = 1 << 2; + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[repr(C)] +pub struct MTLSizeAndAlign { + pub size: NSUInteger, + pub align: NSUInteger, +} + +pub enum MTLResource {} + +foreign_obj_type! { + type CType = MTLResource; + pub struct Resource; + pub struct ResourceRef; +} + +impl ResourceRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } + + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn cpu_cache_mode(&self) -> MTLCPUCacheMode { + unsafe { msg_send![self, cpuCacheMode] } + } + + pub fn storage_mode(&self) -> MTLStorageMode { + unsafe { msg_send![self, storageMode] } + } + + pub fn set_purgeable_state(&self, state: MTLPurgeableState) -> MTLPurgeableState { + unsafe { msg_send![self, setPurgeableState: state] } + } + + /// Only available on macOS 10.13+ & iOS 10.11+ + pub fn allocated_size(&self) -> NSUInteger { + unsafe { msg_send![self, allocatedSize] } + } +} diff --git a/third_party/rust/metal/src/sampler.rs b/third_party/rust/metal/src/sampler.rs new file mode 100644 index 0000000000..f0d61a5396 --- /dev/null +++ b/third_party/rust/metal/src/sampler.rs @@ -0,0 +1,132 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use cocoa_foundation::foundation::NSUInteger; + +use crate::depthstencil::MTLCompareFunction; + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLSamplerMinMagFilter { + Nearest = 0, + Linear = 1, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLSamplerMipFilter { + NotMipmapped = 0, + Nearest = 1, + Linear = 2, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLSamplerAddressMode { + ClampToEdge = 0, + MirrorClampToEdge = 1, + Repeat = 2, + MirrorRepeat = 3, + ClampToZero = 4, + ClampToBorderColor = 5, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLSamplerBorderColor { + TransparentBlack = 0, + OpaqueBlack = 1, + OpaqueWhite = 2, +} + +pub enum MTLSamplerDescriptor {} + +foreign_obj_type! { + type CType = MTLSamplerDescriptor; + pub struct SamplerDescriptor; + pub struct SamplerDescriptorRef; +} + +impl SamplerDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLSamplerDescriptor); + msg_send![class, new] + } + } +} + +impl SamplerDescriptorRef { + pub fn set_min_filter(&self, filter: MTLSamplerMinMagFilter) { + unsafe { msg_send![self, setMinFilter: filter] } + } + + pub fn set_mag_filter(&self, filter: MTLSamplerMinMagFilter) { + unsafe { msg_send![self, setMagFilter: filter] } + } + + pub fn set_mip_filter(&self, filter: MTLSamplerMipFilter) { + unsafe { msg_send![self, setMipFilter: filter] } + } + + pub fn set_address_mode_s(&self, mode: MTLSamplerAddressMode) { + unsafe { msg_send![self, setSAddressMode: mode] } + } + + pub fn set_address_mode_t(&self, mode: MTLSamplerAddressMode) { + unsafe { msg_send![self, setTAddressMode: mode] } + } + + pub fn set_address_mode_r(&self, mode: MTLSamplerAddressMode) { + unsafe { msg_send![self, setRAddressMode: mode] } + } + + pub fn set_max_anisotropy(&self, anisotropy: NSUInteger) { + unsafe { msg_send![self, setMaxAnisotropy: anisotropy] } + } + + pub fn set_compare_function(&self, func: MTLCompareFunction) { + unsafe { msg_send![self, setCompareFunction: func] } + } + + #[cfg(feature = "private")] + pub unsafe fn set_lod_bias(&self, bias: f32) { + msg_send![self, setLodBias: bias] + } + + pub fn set_lod_min_clamp(&self, clamp: f32) { + unsafe { msg_send![self, setLodMinClamp: clamp] } + } + + pub fn set_lod_max_clamp(&self, clamp: f32) { + unsafe { msg_send![self, setLodMaxClamp: clamp] } + } + + pub fn set_lod_average(&self, enable: bool) { + unsafe { msg_send![self, setLodAverage: enable] } + } + + pub fn set_normalized_coordinates(&self, enable: bool) { + unsafe { msg_send![self, setNormalizedCoordinates: enable] } + } + + pub fn set_support_argument_buffers(&self, enable: bool) { + unsafe { msg_send![self, setSupportArgumentBuffers: enable] } + } + + pub fn set_border_color(&self, color: MTLSamplerBorderColor) { + unsafe { msg_send![self, setBorderColor: color] } + } +} + +pub enum MTLSamplerState {} + +foreign_obj_type! { + type CType = MTLSamplerState; + pub struct SamplerState; + pub struct SamplerStateRef; +} diff --git a/third_party/rust/metal/src/texture.rs b/third_party/rust/metal/src/texture.rs new file mode 100644 index 0000000000..4d338f5082 --- /dev/null +++ b/third_party/rust/metal/src/texture.rs @@ -0,0 +1,324 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use cocoa_foundation::foundation::{NSRange, NSUInteger}; +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub enum MTLTextureType { + D1 = 0, + D1Array = 1, + D2 = 2, + D2Array = 3, + D2Multisample = 4, + Cube = 5, + CubeArray = 6, + D3 = 7, +} + +bitflags! { + pub struct MTLTextureUsage: NSUInteger { + const Unknown = 0x0000; + const ShaderRead = 0x0001; + const ShaderWrite = 0x0002; + const RenderTarget = 0x0004; + const PixelFormatView = 0x0010; + } +} + +pub enum MTLTextureDescriptor {} + +foreign_obj_type! { + type CType = MTLTextureDescriptor; + pub struct TextureDescriptor; + pub struct TextureDescriptorRef; +} + +impl TextureDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLTextureDescriptor); + msg_send![class, new] + } + } +} + +impl TextureDescriptorRef { + pub fn texture_type(&self) -> MTLTextureType { + unsafe { msg_send![self, textureType] } + } + + pub fn set_texture_type(&self, texture_type: MTLTextureType) { + unsafe { msg_send![self, setTextureType: texture_type] } + } + + pub fn pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, pixelFormat] } + } + + pub fn set_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setPixelFormat: pixel_format] } + } + + pub fn width(&self) -> NSUInteger { + unsafe { msg_send![self, width] } + } + + pub fn set_width(&self, width: NSUInteger) { + unsafe { msg_send![self, setWidth: width] } + } + + pub fn height(&self) -> NSUInteger { + unsafe { msg_send![self, height] } + } + + pub fn set_height(&self, height: NSUInteger) { + unsafe { msg_send![self, setHeight: height] } + } + + pub fn depth(&self) -> NSUInteger { + unsafe { msg_send![self, depth] } + } + + pub fn set_depth(&self, depth: NSUInteger) { + unsafe { msg_send![self, setDepth: depth] } + } + + pub fn mipmap_level_count(&self) -> NSUInteger { + unsafe { msg_send![self, mipmapLevelCount] } + } + + pub fn set_mipmap_level_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMipmapLevelCount: count] } + } + + pub fn sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, sampleCount] } + } + + pub fn set_sample_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setSampleCount: count] } + } + + pub fn array_length(&self) -> NSUInteger { + unsafe { msg_send![self, arrayLength] } + } + + pub fn set_array_length(&self, length: NSUInteger) { + unsafe { msg_send![self, setArrayLength: length] } + } + + pub fn resource_options(&self) -> MTLResourceOptions { + unsafe { msg_send![self, resourceOptions] } + } + + pub fn set_resource_options(&self, options: MTLResourceOptions) { + unsafe { msg_send![self, setResourceOptions: options] } + } + + pub fn cpu_cache_mode(&self) -> MTLCPUCacheMode { + unsafe { msg_send![self, cpuCacheMode] } + } + + pub fn set_cpu_cache_mode(&self, mode: MTLCPUCacheMode) { + unsafe { msg_send![self, setCpuCacheMode: mode] } + } + + pub fn storage_mode(&self) -> MTLStorageMode { + unsafe { msg_send![self, storageMode] } + } + + pub fn set_storage_mode(&self, mode: MTLStorageMode) { + unsafe { msg_send![self, setStorageMode: mode] } + } + + pub fn usage(&self) -> MTLTextureUsage { + unsafe { msg_send![self, usage] } + } + + pub fn set_usage(&self, usage: MTLTextureUsage) { + unsafe { msg_send![self, setUsage: usage] } + } +} + +pub enum MTLTexture {} + +foreign_obj_type! { + type CType = MTLTexture; + pub struct Texture; + pub struct TextureRef; + type ParentType = ResourceRef; +} + +impl TextureRef { + #[deprecated(since = "0.13.0")] + pub fn root_resource(&self) -> Option<&ResourceRef> { + unsafe { msg_send![self, rootResource] } + } + + pub fn parent_texture(&self) -> Option<&TextureRef> { + unsafe { msg_send![self, parentTexture] } + } + + pub fn parent_relative_level(&self) -> NSUInteger { + unsafe { msg_send![self, parentRelativeLevel] } + } + + pub fn parent_relative_slice(&self) -> NSUInteger { + unsafe { msg_send![self, parentRelativeSlice] } + } + + pub fn buffer(&self) -> Option<&BufferRef> { + unsafe { msg_send![self, buffer] } + } + + pub fn buffer_offset(&self) -> NSUInteger { + unsafe { msg_send![self, bufferOffset] } + } + + pub fn buffer_stride(&self) -> NSUInteger { + unsafe { msg_send![self, bufferBytesPerRow] } + } + + pub fn texture_type(&self) -> MTLTextureType { + unsafe { msg_send![self, textureType] } + } + + pub fn pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, pixelFormat] } + } + + pub fn width(&self) -> NSUInteger { + unsafe { msg_send![self, width] } + } + + pub fn height(&self) -> NSUInteger { + unsafe { msg_send![self, height] } + } + + pub fn depth(&self) -> NSUInteger { + unsafe { msg_send![self, depth] } + } + + pub fn mipmap_level_count(&self) -> NSUInteger { + unsafe { msg_send![self, mipmapLevelCount] } + } + + pub fn sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, sampleCount] } + } + + pub fn array_length(&self) -> NSUInteger { + unsafe { msg_send![self, arrayLength] } + } + + pub fn usage(&self) -> MTLTextureUsage { + unsafe { msg_send![self, usage] } + } + + /// [framebufferOnly Apple Docs](https://developer.apple.com/documentation/metal/mtltexture/1515749-framebufferonly?language=objc) + pub fn framebuffer_only(&self) -> bool { + unsafe { + match msg_send![self, isFramebufferOnly] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn get_bytes( + &self, + bytes: *mut std::ffi::c_void, + stride: NSUInteger, + region: MTLRegion, + mipmap_level: NSUInteger, + ) { + unsafe { + msg_send![self, getBytes:bytes + bytesPerRow:stride + fromRegion:region + mipmapLevel:mipmap_level] + } + } + + pub fn get_bytes_in_slice( + &self, + bytes: *mut std::ffi::c_void, + stride: NSUInteger, + image_stride: NSUInteger, + region: MTLRegion, + mipmap_level: NSUInteger, + slice: NSUInteger, + ) { + unsafe { + msg_send![self, getBytes:bytes + bytesPerRow:stride + bytesPerImage:image_stride + fromRegion:region + mipmapLevel:mipmap_level + slice:slice] + } + } + + pub fn replace_region( + &self, + region: MTLRegion, + mipmap_level: NSUInteger, + bytes: *const std::ffi::c_void, + stride: NSUInteger, + ) { + unsafe { + msg_send![self, replaceRegion:region + mipmapLevel:mipmap_level + withBytes:bytes + bytesPerRow:stride] + } + } + + pub fn replace_region_in_slice( + &self, + region: MTLRegion, + mipmap_level: NSUInteger, + slice: NSUInteger, + bytes: *const std::ffi::c_void, + stride: NSUInteger, + image_stride: NSUInteger, + ) { + unsafe { + msg_send![self, replaceRegion:region + mipmapLevel:mipmap_level + slice:slice + withBytes:bytes + bytesPerRow:stride + bytesPerImage:image_stride] + } + } + + pub fn new_texture_view(&self, pixel_format: MTLPixelFormat) -> Texture { + unsafe { msg_send![self, newTextureViewWithPixelFormat: pixel_format] } + } + + pub fn new_texture_view_from_slice( + &self, + pixel_format: MTLPixelFormat, + texture_type: MTLTextureType, + mipmap_levels: NSRange, + slices: NSRange, + ) -> Texture { + unsafe { + msg_send![self, newTextureViewWithPixelFormat:pixel_format + textureType:texture_type + levels:mipmap_levels + slices:slices] + } + } +} diff --git a/third_party/rust/metal/src/types.rs b/third_party/rust/metal/src/types.rs new file mode 100644 index 0000000000..313a5eaf82 --- /dev/null +++ b/third_party/rust/metal/src/types.rs @@ -0,0 +1,39 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use cocoa_foundation::foundation::NSUInteger; +use std::default::Default; + +#[repr(C)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)] +pub struct MTLOrigin { + pub x: NSUInteger, + pub y: NSUInteger, + pub z: NSUInteger, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)] +pub struct MTLSize { + pub width: NSUInteger, + pub height: NSUInteger, + pub depth: NSUInteger, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)] +pub struct MTLRegion { + pub origin: MTLOrigin, + pub size: MTLSize, +} + +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct MTLSamplePosition { + pub x: f32, + pub y: f32, +} diff --git a/third_party/rust/metal/src/vertexdescriptor.rs b/third_party/rust/metal/src/vertexdescriptor.rs new file mode 100644 index 0000000000..5fba52f659 --- /dev/null +++ b/third_party/rust/metal/src/vertexdescriptor.rs @@ -0,0 +1,248 @@ +// Copyright 2016 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use cocoa_foundation::foundation::NSUInteger; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLVertexFormat { + Invalid = 0, + UChar2 = 1, + UChar3 = 2, + UChar4 = 3, + Char2 = 4, + Char3 = 5, + Char4 = 6, + UChar2Normalized = 7, + UChar3Normalized = 8, + UChar4Normalized = 9, + Char2Normalized = 10, + Char3Normalized = 11, + Char4Normalized = 12, + UShort2 = 13, + UShort3 = 14, + UShort4 = 15, + Short2 = 16, + Short3 = 17, + Short4 = 18, + UShort2Normalized = 19, + UShort3Normalized = 20, + UShort4Normalized = 21, + Short2Normalized = 22, + Short3Normalized = 23, + Short4Normalized = 24, + Half2 = 25, + Half3 = 26, + Half4 = 27, + Float = 28, + Float2 = 29, + Float3 = 30, + Float4 = 31, + Int = 32, + Int2 = 33, + Int3 = 34, + Int4 = 35, + UInt = 36, + UInt2 = 37, + UInt3 = 38, + UInt4 = 39, + Int1010102Normalized = 40, + UInt1010102Normalized = 41, + UChar4Normalized_BGRA = 42, + UChar = 45, + Char = 46, + UCharNormalized = 47, + CharNormalized = 48, + UShort = 49, + Short = 50, + UShortNormalized = 51, + ShortNormalized = 52, + Half = 53, +} + +#[repr(u64)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum MTLVertexStepFunction { + Constant = 0, + PerVertex = 1, + PerInstance = 2, + PerPatch = 3, + PerPatchControlPoint = 4, +} + +pub enum MTLVertexBufferLayoutDescriptor {} + +foreign_obj_type! { + type CType = MTLVertexBufferLayoutDescriptor; + pub struct VertexBufferLayoutDescriptor; + pub struct VertexBufferLayoutDescriptorRef; +} + +impl VertexBufferLayoutDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLVertexBufferLayoutDescriptor); + msg_send![class, new] + } + } +} + +impl VertexBufferLayoutDescriptorRef { + pub fn stride(&self) -> NSUInteger { + unsafe { msg_send![self, stride] } + } + + pub fn set_stride(&self, stride: NSUInteger) { + unsafe { msg_send![self, setStride: stride] } + } + + pub fn step_function(&self) -> MTLVertexStepFunction { + unsafe { msg_send![self, stepFunction] } + } + + pub fn set_step_function(&self, func: MTLVertexStepFunction) { + unsafe { msg_send![self, setStepFunction: func] } + } + + pub fn step_rate(&self) -> NSUInteger { + unsafe { msg_send![self, stepRate] } + } + + pub fn set_step_rate(&self, step_rate: NSUInteger) { + unsafe { msg_send![self, setStepRate: step_rate] } + } +} + +pub enum MTLVertexBufferLayoutDescriptorArray {} + +foreign_obj_type! { + type CType = MTLVertexBufferLayoutDescriptorArray; + pub struct VertexBufferLayoutDescriptorArray; + pub struct VertexBufferLayoutDescriptorArrayRef; +} + +impl VertexBufferLayoutDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&VertexBufferLayoutDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + layout: Option<&VertexBufferLayoutDescriptorRef>, + ) { + unsafe { + msg_send![self, setObject:layout + atIndexedSubscript:index] + } + } +} + +pub enum MTLVertexAttributeDescriptor {} + +foreign_obj_type! { + type CType = MTLVertexAttributeDescriptor; + pub struct VertexAttributeDescriptor; + pub struct VertexAttributeDescriptorRef; +} + +impl VertexAttributeDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLVertexAttributeDescriptor); + msg_send![class, new] + } + } +} + +impl VertexAttributeDescriptorRef { + pub fn format(&self) -> MTLVertexFormat { + unsafe { msg_send![self, format] } + } + + pub fn set_format(&self, format: MTLVertexFormat) { + unsafe { msg_send![self, setFormat: format] } + } + + pub fn offset(&self) -> NSUInteger { + unsafe { msg_send![self, offset] } + } + + pub fn set_offset(&self, offset: NSUInteger) { + unsafe { msg_send![self, setOffset: offset] } + } + + pub fn buffer_index(&self) -> NSUInteger { + unsafe { msg_send![self, bufferIndex] } + } + + pub fn set_buffer_index(&self, index: NSUInteger) { + unsafe { msg_send![self, setBufferIndex: index] } + } +} + +pub enum MTLVertexAttributeDescriptorArray {} + +foreign_obj_type! { + type CType = MTLVertexAttributeDescriptorArray; + pub struct VertexAttributeDescriptorArray; + pub struct VertexAttributeDescriptorArrayRef; +} + +impl VertexAttributeDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&VertexAttributeDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + attribute: Option<&VertexAttributeDescriptorRef>, + ) { + unsafe { + msg_send![self, setObject:attribute + atIndexedSubscript:index] + } + } +} + +pub enum MTLVertexDescriptor {} + +foreign_obj_type! { + type CType = MTLVertexDescriptor; + pub struct VertexDescriptor; + pub struct VertexDescriptorRef; +} + +impl VertexDescriptor { + pub fn new<'a>() -> &'a VertexDescriptorRef { + unsafe { + let class = class!(MTLVertexDescriptor); + msg_send![class, vertexDescriptor] + } + } +} + +impl VertexDescriptorRef { + pub fn layouts(&self) -> &VertexBufferLayoutDescriptorArrayRef { + unsafe { msg_send![self, layouts] } + } + + pub fn attributes(&self) -> &VertexAttributeDescriptorArrayRef { + unsafe { msg_send![self, attributes] } + } + + #[cfg(feature = "private")] + pub unsafe fn serialize_descriptor(&self) -> *mut std::ffi::c_void { + msg_send![self, newSerializedDescriptor] + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} |