summaryrefslogtreecommitdiffstats
path: root/third_party/rust/metal
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/metal
parentInitial commit. (diff)
downloadfirefox-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')
-rw-r--r--third_party/rust/metal/.cargo-checksum.json1
-rw-r--r--third_party/rust/metal/Cargo.lock1070
-rw-r--r--third_party/rust/metal/Cargo.toml100
-rw-r--r--third_party/rust/metal/LICENSE-APACHE201
-rw-r--r--third_party/rust/metal/LICENSE-MIT25
-rw-r--r--third_party/rust/metal/Makefile12
-rw-r--r--third_party/rust/metal/README.md32
-rw-r--r--third_party/rust/metal/bors.toml8
-rw-r--r--third_party/rust/metal/examples/argument-buffer/main.rs43
-rw-r--r--third_party/rust/metal/examples/bind/main.rs42
-rw-r--r--third_party/rust/metal/examples/caps/main.rs32
-rw-r--r--third_party/rust/metal/examples/circle/README.md11
-rw-r--r--third_party/rust/metal/examples/circle/main.rs215
-rw-r--r--third_party/rust/metal/examples/circle/screenshot.pngbin0 -> 479786 bytes
-rw-r--r--third_party/rust/metal/examples/circle/shaders.metal39
-rw-r--r--third_party/rust/metal/examples/circle/shaders.metallibbin0 -> 6304 bytes
-rw-r--r--third_party/rust/metal/examples/compute/compute-argument-buffer.metal14
-rw-r--r--third_party/rust/metal/examples/compute/compute-argument-buffer.rs101
-rw-r--r--third_party/rust/metal/examples/compute/embedded-lib.rs31
-rw-r--r--third_party/rust/metal/examples/compute/main.rs97
-rw-r--r--third_party/rust/metal/examples/compute/shaders.metal10
-rw-r--r--third_party/rust/metal/examples/compute/shaders.metallibbin0 -> 3209 bytes
-rw-r--r--third_party/rust/metal/examples/headless-render/README.md11
-rw-r--r--third_party/rust/metal/examples/headless-render/main.rs159
-rw-r--r--third_party/rust/metal/examples/headless-render/screenshot.pngbin0 -> 88605 bytes
-rw-r--r--third_party/rust/metal/examples/library/main.rs17
-rw-r--r--third_party/rust/metal/examples/reflection/main.rs83
-rw-r--r--third_party/rust/metal/examples/window/README.md11
-rw-r--r--third_party/rust/metal/examples/window/main.rs178
-rw-r--r--third_party/rust/metal/examples/window/screenshot.pngbin0 -> 55104 bytes
-rw-r--r--third_party/rust/metal/examples/window/shaders.metal32
-rw-r--r--third_party/rust/metal/examples/window/shaders.metallibbin0 -> 6092 bytes
-rw-r--r--third_party/rust/metal/src/argument.rs324
-rw-r--r--third_party/rust/metal/src/buffer.rs55
-rw-r--r--third_party/rust/metal/src/capturedescriptor.rs79
-rw-r--r--third_party/rust/metal/src/capturemanager.rs107
-rw-r--r--third_party/rust/metal/src/commandbuffer.rs129
-rw-r--r--third_party/rust/metal/src/commandqueue.rs44
-rw-r--r--third_party/rust/metal/src/constants.rs137
-rw-r--r--third_party/rust/metal/src/depthstencil.rs166
-rw-r--r--third_party/rust/metal/src/device.rs1753
-rw-r--r--third_party/rust/metal/src/drawable.rs20
-rw-r--r--third_party/rust/metal/src/encoder.rs1121
-rw-r--r--third_party/rust/metal/src/heap.rs110
-rw-r--r--third_party/rust/metal/src/indirect_encoder.rs349
-rw-r--r--third_party/rust/metal/src/lib.rs433
-rw-r--r--third_party/rust/metal/src/library.rs259
-rw-r--r--third_party/rust/metal/src/pipeline/compute.rs354
-rw-r--r--third_party/rust/metal/src/pipeline/mod.rs70
-rw-r--r--third_party/rust/metal/src/pipeline/render.rs432
-rw-r--r--third_party/rust/metal/src/renderpass.rs334
-rw-r--r--third_party/rust/metal/src/resource.rs115
-rw-r--r--third_party/rust/metal/src/sampler.rs132
-rw-r--r--third_party/rust/metal/src/texture.rs324
-rw-r--r--third_party/rust/metal/src/types.rs39
-rw-r--r--third_party/rust/metal/src/vertexdescriptor.rs248
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
new file mode 100644
index 0000000000..38f86e733d
--- /dev/null
+++ b/third_party/rust/metal/examples/circle/screenshot.png
Binary files differ
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
new file mode 100644
index 0000000000..cbb9bc5e5a
--- /dev/null
+++ b/third_party/rust/metal/examples/circle/shaders.metallib
Binary files differ
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
new file mode 100644
index 0000000000..af7cb17240
--- /dev/null
+++ b/third_party/rust/metal/examples/compute/shaders.metallib
Binary files differ
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
new file mode 100644
index 0000000000..2af9c5895f
--- /dev/null
+++ b/third_party/rust/metal/examples/headless-render/screenshot.png
Binary files differ
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
new file mode 100644
index 0000000000..9f5eba8ccf
--- /dev/null
+++ b/third_party/rust/metal/examples/window/screenshot.png
Binary files differ
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
new file mode 100644
index 0000000000..a182b718fa
--- /dev/null
+++ b/third_party/rust/metal/examples/window/shaders.metallib
Binary files differ
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] }
+ }
+}