diff --git a/Cargo.lock b/Cargo.lock index bcaa1d64..32b8b3d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bindgen" @@ -79,23 +79,23 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.76", + "syn", ] [[package]] name = "bit-set" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0481a0e032742109b1133a095184ee93d88f3dc9e0d28a5d033dc77a073f44f" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" @@ -126,9 +126,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "cexpr" @@ -172,37 +172,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "com" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "com_macros_support" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -230,16 +199,6 @@ dependencies = [ "libc", ] -[[package]] -name = "d3d12" -version = "22.0.0" -source = "git+https://github.com/gfx-rs/wgpu?tag=v22.1.0#5c5c8b1d4d2d965fbd10b290ee26f4e7eb158d7c" -dependencies = [ - "bitflags 2.6.0", - "libloading", - "winapi", -] - [[package]] name = "document-features" version = "0.2.10" @@ -285,7 +244,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -313,9 +272,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "glow" -version = "0.13.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" dependencies = [ "js-sys", "slotmap", @@ -353,14 +312,13 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" dependencies = [ "log", "presser", "thiserror", - "winapi", "windows", ] @@ -372,7 +330,7 @@ checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" dependencies = [ "bitflags 2.6.0", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -395,19 +353,10 @@ dependencies = [ ] [[package]] -name = "hassle-rs" -version = "0.11.0" +name = "hashbrown" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" -dependencies = [ - "bitflags 2.6.0", - "com", - "libc", - "libloading", - "thiserror", - "widestring", - "winapi", -] +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hexf-parse" @@ -417,12 +366,12 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", "serde", ] @@ -443,9 +392,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -469,9 +418,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" @@ -543,8 +492,8 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "naga" -version = "22.1.0" -source = "git+https://github.com/gfx-rs/wgpu?tag=v22.1.0#5c5c8b1d4d2d965fbd10b290ee26f4e7eb158d7c" +version = "23.0.0" +source = "git+https://github.com/gfx-rs/wgpu?tag=v23.0.0#08c9d8c397a4d3943c53d66c077c85236ff11f46" dependencies = [ "arrayvec", "bit-set", @@ -594,9 +543,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "parking_lot" @@ -639,9 +588,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "pp-rs" @@ -665,14 +614,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ "proc-macro2", - "syn 2.0.76", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] @@ -706,18 +655,18 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -727,9 +676,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -738,9 +687,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "renderdoc-sys" @@ -762,22 +711,22 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -812,20 +761,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -843,41 +781,41 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "version_check" @@ -887,9 +825,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -898,24 +836,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -923,28 +861,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -952,8 +890,8 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "22.1.0" -source = "git+https://github.com/gfx-rs/wgpu?tag=v22.1.0#5c5c8b1d4d2d965fbd10b290ee26f4e7eb158d7c" +version = "23.0.0" +source = "git+https://github.com/gfx-rs/wgpu?tag=v23.0.0#08c9d8c397a4d3943c53d66c077c85236ff11f46" dependencies = [ "arrayvec", "bit-vec", @@ -978,8 +916,8 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "22.0.0" -source = "git+https://github.com/gfx-rs/wgpu?tag=v22.1.0#5c5c8b1d4d2d965fbd10b290ee26f4e7eb158d7c" +version = "23.0.0" +source = "git+https://github.com/gfx-rs/wgpu?tag=v23.0.0#08c9d8c397a4d3943c53d66c077c85236ff11f46" dependencies = [ "android_system_properties", "arrayvec", @@ -987,15 +925,14 @@ dependencies = [ "bit-set", "bitflags 2.6.0", "block", + "bytemuck", "cfg_aliases", "core-graphics-types", - "d3d12", "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hassle-rs", "js-sys", "khronos-egl", "libc", @@ -1017,7 +954,8 @@ dependencies = [ "wasm-bindgen", "web-sys", "wgpu-types", - "winapi", + "windows", + "windows-core", ] [[package]] @@ -1025,6 +963,7 @@ name = "wgpu-native" version = "0.0.0" dependencies = [ "bindgen", + "bitflags 2.6.0", "log", "naga", "parking_lot", @@ -1040,8 +979,8 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "22.0.0" -source = "git+https://github.com/gfx-rs/wgpu?tag=v22.1.0#5c5c8b1d4d2d965fbd10b290ee26f4e7eb158d7c" +version = "23.0.0" +source = "git+https://github.com/gfx-rs/wgpu?tag=v23.0.0#08c9d8c397a4d3943c53d66c077c85236ff11f46" dependencies = [ "bitflags 2.6.0", "js-sys", @@ -1050,58 +989,75 @@ dependencies = [ ] [[package]] -name = "widestring" -version = "1.1.0" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-core", + "windows-targets", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] [[package]] -name = "winapi-util" -version = "0.1.9" +name = "windows-implement" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ - "windows-sys", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-interface" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "windows" -version = "0.52.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-core", "windows-targets", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ + "windows-result", "windows-targets", ] @@ -1180,9 +1136,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "xml-rs" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" [[package]] name = "zerocopy" @@ -1201,5 +1157,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index bf7ebdd2..8a6437aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,22 +23,22 @@ resolver = "2" [workspace.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -tag = "v22.1.0" +tag = "v23.0.0" [workspace.dependencies.wgt] package = "wgpu-types" git = "https://github.com/gfx-rs/wgpu" -tag = "v22.1.0" +tag = "v23.0.0" [workspace.dependencies.hal] package = "wgpu-hal" git = "https://github.com/gfx-rs/wgpu" -tag = "v22.1.0" +tag = "v23.0.0" [workspace.dependencies.naga] package = "naga" git = "https://github.com/gfx-rs/wgpu" -tag = "v22.1.0" +tag = "v23.0.0" [lib] crate-type = ["cdylib", "staticlib"] @@ -134,9 +134,8 @@ hal = { workspace = true, features = ["renderdoc"] } [target.'cfg(windows)'.dependencies] hal = { workspace = true, features = [ - "dxc_shader_compiler", + "dx12", "renderdoc", - "windows_rs", ] } [dependencies.wgt] @@ -157,6 +156,7 @@ log = "0.4" thiserror = "1" parking_lot = "0.12" smallvec = "1" +bitflags = "2" [build-dependencies] bindgen = "0.70" diff --git a/build.rs b/build.rs index b26a4f19..3a3abaf6 100644 --- a/build.rs +++ b/build.rs @@ -41,7 +41,8 @@ fn main() { .prepend_enum_name(false) .size_t_is_usize(true) .ignore_functions() - .layout_tests(true); + .layout_tests(true) + .clang_macro_fallback(); for (old_name, new_name) in types_to_rename { let line = format!("pub type {old_name} = *const crate::{new_name};"); diff --git a/examples/capture/CMakeLists.txt b/examples/capture/CMakeLists.txt index db148c9a..606a33ca 100644 --- a/examples/capture/CMakeLists.txt +++ b/examples/capture/CMakeLists.txt @@ -16,7 +16,7 @@ include_directories(${CMAKE_SOURCE_DIR}/../ffi/webgpu-headers) include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) set(OS_LIBRARIES "-lm -ldl") elseif(APPLE) diff --git a/examples/capture/main.c b/examples/capture/main.c index e7133836..b148765f 100644 --- a/examples/capture/main.c +++ b/examples/capture/main.c @@ -14,21 +14,27 @@ const size_t IMAGE_HEIGHT = 200; const size_t COPY_BYTES_PER_ROW_ALIGNMENT = 256; static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *userdata) { + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUAdapter *)userdata = adapter; + UNUSED(userdata2) + *(WGPUAdapter *)userdata1 = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, char const *message, - void *userdata) { + WGPUDevice device, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUDevice *)userdata = device; + UNUSED(userdata2) + *(WGPUDevice *)userdata1 = device; } -static void handle_buffer_map(WGPUBufferMapAsyncStatus status, void *userdata) { - UNUSED(userdata) +static void handle_buffer_map(WGPUMapAsyncStatus status, + WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(message) + UNUSED(userdata1) + UNUSED(userdata2) printf(LOG_PREFIX " buffer_map status=%#.8x\n", status); } @@ -67,14 +73,21 @@ int main(int argc, char *argv[]) { assert(instance); WGPUAdapter adapter = NULL; - wgpuInstanceRequestAdapter(instance, NULL, handle_request_adapter, - (void *)&adapter); + wgpuInstanceRequestAdapter(instance, NULL, + (const WGPURequestAdapterCallbackInfo){ + .callback = handle_request_adapter, + .userdata1 = &adapter + }); assert(adapter); WGPUDevice device = NULL; - wgpuAdapterRequestDevice(adapter, NULL, handle_request_device, - (void *)&device); + wgpuAdapterRequestDevice(adapter, NULL, + (const WGPURequestDeviceCallbackInfo){ + .callback = handle_request_device, + .userdata1 = &device + }); assert(device); + WGPUQueue queue = wgpuDeviceGetQueue(device); assert(queue); @@ -86,7 +99,7 @@ int main(int argc, char *argv[]) { WGPUBuffer output_buffer = wgpuDeviceCreateBuffer( device, &(const WGPUBufferDescriptor){ - .label = "output_buffer", + .label = {"output_buffer", WGPU_STRLEN}, .size = buffer_size, .usage = WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst, .mappedAtCreation = false, @@ -102,7 +115,7 @@ int main(int argc, char *argv[]) { WGPUTexture texture = wgpuDeviceCreateTexture( device, &(const WGPUTextureDescriptor){ - .label = "texture", + .label = {"texture", WGPU_STRLEN}, .size = texture_extent, .mipLevelCount = 1, .sampleCount = 1, @@ -116,13 +129,13 @@ int main(int argc, char *argv[]) { WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( device, &(const WGPUCommandEncoderDescriptor){ - .label = "command_encoder", + .label = {"command_encoder", WGPU_STRLEN}, }); assert(command_encoder); WGPURenderPassEncoder render_pass_encoder = wgpuCommandEncoderBeginRenderPass( command_encoder, &(const WGPURenderPassDescriptor){ - .label = "rende_pass_encoder", + .label = {"rende_pass_encoder", WGPU_STRLEN}, .colorAttachmentCount = 1, .colorAttachments = (const WGPURenderPassColorAttachment[]){ @@ -148,16 +161,16 @@ int main(int argc, char *argv[]) { wgpuCommandEncoderCopyTextureToBuffer( command_encoder, - &(const WGPUImageCopyTexture){ + &(const WGPUTexelCopyTextureInfo){ .texture = texture, .mipLevel = 0, .origin = (const WGPUOrigin3D){.x = 0, .y = 0, .z = 0}, .aspect = WGPUTextureAspect_All, }, - &(const WGPUImageCopyBuffer){ + &(const WGPUTexelCopyBufferInfo){ .buffer = output_buffer, .layout = - (const WGPUTextureDataLayout){ + (const WGPUTexelCopyBufferLayout){ .offset = 0, .bytesPerRow = buffer_dimensions.padded_bytes_per_row, .rowsPerImage = WGPU_COPY_STRIDE_UNDEFINED, @@ -167,14 +180,16 @@ int main(int argc, char *argv[]) { WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish( command_encoder, &(const WGPUCommandBufferDescriptor){ - .label = "command_buffer", + .label = {"command_buffer", WGPU_STRLEN}, }); assert(command_buffer); wgpuQueueSubmit(queue, 1, (const WGPUCommandBuffer[]){command_buffer}); wgpuBufferMapAsync(output_buffer, WGPUMapMode_Read, 0, buffer_size, - handle_buffer_map, NULL); + (const WGPUBufferMapCallbackInfo){ + .callback = handle_buffer_map + }); wgpuDevicePoll(device, true, NULL); uint8_t *buf = diff --git a/examples/compute/CMakeLists.txt b/examples/compute/CMakeLists.txt index e6efecfe..5f039e71 100644 --- a/examples/compute/CMakeLists.txt +++ b/examples/compute/CMakeLists.txt @@ -14,7 +14,7 @@ include_directories(${CMAKE_SOURCE_DIR}/../ffi/webgpu-headers) include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) set(OS_LIBRARIES "-lm -ldl") elseif(APPLE) diff --git a/examples/compute/main.c b/examples/compute/main.c index 03dcaeba..19f6c3a3 100644 --- a/examples/compute/main.c +++ b/examples/compute/main.c @@ -7,21 +7,26 @@ #define LOG_PREFIX "[compute]" static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *userdata) { + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUAdapter *)userdata = adapter; + UNUSED(userdata2) + *(WGPUAdapter *)userdata1 = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, char const *message, - void *userdata) { + WGPUDevice device, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUDevice *)userdata = device; + UNUSED(userdata2) + *(WGPUDevice *)userdata1 = device; } -static void handle_buffer_map(WGPUBufferMapAsyncStatus status, void *userdata) { - UNUSED(userdata) +static void handle_buffer_map(WGPUMapAsyncStatus status, + WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata1) + UNUSED(userdata2) printf(LOG_PREFIX " buffer_map status=%#.8x\n", status); } @@ -38,13 +43,19 @@ int main(int argc, char *argv[]) { assert(instance); WGPUAdapter adapter = NULL; - wgpuInstanceRequestAdapter(instance, NULL, handle_request_adapter, - (void *)&adapter); + wgpuInstanceRequestAdapter(instance, NULL, + (const WGPURequestAdapterCallbackInfo){ + .callback = handle_request_adapter, + .userdata1 = &adapter + }); assert(adapter); WGPUDevice device = NULL; - wgpuAdapterRequestDevice(adapter, NULL, handle_request_device, - (void *)&device); + wgpuAdapterRequestDevice(adapter, NULL, + (const WGPURequestDeviceCallbackInfo){ + .callback = handle_request_device, + .userdata1 = &device + }); assert(device); WGPUQueue queue = wgpuDeviceGetQueue(device); @@ -56,7 +67,7 @@ int main(int argc, char *argv[]) { WGPUBuffer staging_buffer = wgpuDeviceCreateBuffer( device, &(const WGPUBufferDescriptor){ - .label = "staging_buffer", + .label = {"staging_buffer", WGPU_STRLEN}, .usage = WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst, .size = numbers_size, .mappedAtCreation = false, @@ -65,7 +76,7 @@ int main(int argc, char *argv[]) { WGPUBuffer storage_buffer = wgpuDeviceCreateBuffer( device, &(const WGPUBufferDescriptor){ - .label = "storage_buffer", + .label = {"storage_buffer", WGPU_STRLEN}, .usage = WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst | WGPUBufferUsage_CopySrc, .size = numbers_size, @@ -75,11 +86,11 @@ int main(int argc, char *argv[]) { WGPUComputePipeline compute_pipeline = wgpuDeviceCreateComputePipeline( device, &(const WGPUComputePipelineDescriptor){ - .label = "compute_pipeline", + .label = {"compute_pipeline", WGPU_STRLEN}, .compute = (const WGPUProgrammableStageDescriptor){ .module = shader_module, - .entryPoint = "main", + .entryPoint = {"main", WGPU_STRLEN}, }, }); assert(compute_pipeline); @@ -90,7 +101,7 @@ int main(int argc, char *argv[]) { WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup( device, &(const WGPUBindGroupDescriptor){ - .label = "bind_group", + .label = {"bind_group", WGPU_STRLEN}, .layout = bind_group_layout, .entryCount = 1, .entries = @@ -107,14 +118,14 @@ int main(int argc, char *argv[]) { WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( device, &(const WGPUCommandEncoderDescriptor){ - .label = "command_encoder", + .label = {"command_encoder", WGPU_STRLEN}, }); assert(command_encoder); WGPUComputePassEncoder compute_pass_encoder = wgpuCommandEncoderBeginComputePass(command_encoder, &(const WGPUComputePassDescriptor){ - .label = "compute_pass", + .label = {"compute_pass", WGPU_STRLEN}, }); assert(compute_pass_encoder); @@ -131,7 +142,7 @@ int main(int argc, char *argv[]) { WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish( command_encoder, &(const WGPUCommandBufferDescriptor){ - .label = "command_buffer", + .label = {"command_buffer", WGPU_STRLEN}, }); assert(command_buffer); @@ -139,7 +150,9 @@ int main(int argc, char *argv[]) { wgpuQueueSubmit(queue, 1, &command_buffer); wgpuBufferMapAsync(staging_buffer, WGPUMapMode_Read, 0, numbers_size, - handle_buffer_map, NULL); + (const WGPUBufferMapCallbackInfo){ + .callback = handle_buffer_map + }); wgpuDevicePoll(device, true, NULL); uint32_t *buf = diff --git a/examples/enumerate_adapters/CMakeLists.txt b/examples/enumerate_adapters/CMakeLists.txt index a939822d..65bb1262 100644 --- a/examples/enumerate_adapters/CMakeLists.txt +++ b/examples/enumerate_adapters/CMakeLists.txt @@ -14,7 +14,7 @@ include_directories(${CMAKE_SOURCE_DIR}/../ffi/webgpu-headers) include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) set(OS_LIBRARIES "-lm -ldl") elseif(APPLE) diff --git a/examples/enumerate_adapters/main.c b/examples/enumerate_adapters/main.c index 25b533d8..7e3db303 100644 --- a/examples/enumerate_adapters/main.c +++ b/examples/enumerate_adapters/main.c @@ -26,16 +26,17 @@ int main(int argc, char *argv[]) { wgpuAdapterGetInfo(adapter, &info); printf("WGPUAdapter: %d\n", i); printf("WGPUAdapterInfo {\n" - "\tvendor: %s\n" - "\tarchitecture: %s\n" - "\tdevice: %s\n" - "\tdescription: %s\n" + "\tvendor: %.*s\n" + "\tarchitecture: %.*s\n" + "\tdevice: %.*s\n" + "\tdescription: %.*s\n" "\tbackendType: %#.8x\n" "\tadapterType: %#.8x\n" "\tvendorID: %" PRIu32 "\n" "\tdeviceID: %" PRIu32 "\n" "}\n", - info.vendor, info.architecture, info.device, info.description, + (int) info.vendor.length, info.vendor.data, (int) info.architecture.length, info.architecture.data, + (int) info.device.length, info.device.data, (int) info.description.length, info.description.data, info.backendType, info.adapterType, info.vendorID, info.deviceID); wgpuAdapterInfoFreeMembers(info); diff --git a/examples/framework/framework.c b/examples/framework/framework.c index f0729e51..64ea5533 100644 --- a/examples/framework/framework.c +++ b/examples/framework/framework.c @@ -1,6 +1,6 @@ #include "framework.h" -static void log_callback(WGPULogLevel level, char const *message, +static void log_callback(WGPULogLevel level, WGPUStringView message, void *userdata) { UNUSED(userdata) char *level_str; @@ -23,7 +23,7 @@ static void log_callback(WGPULogLevel level, char const *message, default: level_str = "unknown_level"; } - fprintf(stderr, "[wgpu] [%s] %s\n", level_str, message); + fprintf(stderr, "[wgpu] [%s] %.*s\n", level_str, (int) message.length, message.data); } void frmwrk_setup_logging(WGPULogLevel level) { @@ -64,15 +64,15 @@ WGPUShaderModule frmwrk_load_shader_module(WGPUDevice device, shader_module = wgpuDeviceCreateShaderModule( device, &(const WGPUShaderModuleDescriptor){ - .label = name, + .label = {name, WGPU_STRLEN}, .nextInChain = (const WGPUChainedStruct *)&( - const WGPUShaderModuleWGSLDescriptor){ + const WGPUShaderSourceWGSL){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_ShaderModuleWGSLDescriptor, + .sType = WGPUSType_ShaderSourceWGSL, }, - .code = buf, + .code = {buf, WGPU_STRLEN}, }, }); @@ -92,7 +92,7 @@ WGPUBuffer frmwrk_device_create_buffer_init( assert(descriptor); if (descriptor->content_size == 0) { return wgpuDeviceCreateBuffer(device, &(WGPUBufferDescriptor){ - .label = descriptor->label, + .label = {descriptor->label, WGPU_STRLEN}, .size = 0, .usage = descriptor->usage, .mappedAtCreation = false, @@ -105,7 +105,7 @@ WGPUBuffer frmwrk_device_create_buffer_init( MAX((unpadded_size + align_mask) & ~align_mask, COPY_BUFFER_ALIGNMENT); WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &(WGPUBufferDescriptor){ - .label = descriptor->label, + .label = {descriptor->label, WGPU_STRLEN}, .size = padded_size, .usage = descriptor->usage, .mappedAtCreation = true, @@ -121,7 +121,6 @@ WGPUBuffer frmwrk_device_create_buffer_init( printf("%snumAllocated=%zu\n", prefix, report.numAllocated); \ printf("%snumKeptFromUser=%zu\n", prefix, report.numKeptFromUser); \ printf("%snumReleasedFromUser=%zu\n", prefix, report.numReleasedFromUser); \ - printf("%snumError=%zu\n", prefix, report.numError); \ printf("%selementSize=%zu\n", prefix, report.elementSize) #define print_hub_report(report, prefix) \ @@ -136,6 +135,7 @@ WGPUBuffer frmwrk_device_create_buffer_init( print_registry_report(report.renderBundles, prefix "renderBundles."); \ print_registry_report(report.renderPipelines, prefix "renderPipelines."); \ print_registry_report(report.computePipelines, prefix "computePipelines."); \ + print_registry_report(report.pipelineCaches, prefix "pipelineCaches."); \ print_registry_report(report.querySets, prefix "querySets."); \ print_registry_report(report.textures, prefix "textures."); \ print_registry_report(report.textureViews, prefix "textureViews."); \ @@ -144,34 +144,17 @@ WGPUBuffer frmwrk_device_create_buffer_init( void frmwrk_print_global_report(WGPUGlobalReport report) { printf("struct WGPUGlobalReport {\n"); print_registry_report(report.surfaces, "\tsurfaces."); - - switch (report.backendType) { - case WGPUBackendType_D3D12: - print_hub_report(report.dx12, "\tdx12."); - break; - case WGPUBackendType_Metal: - print_hub_report(report.metal, "\tmetal."); - break; - case WGPUBackendType_Vulkan: - print_hub_report(report.vulkan, "\tvulkan."); - break; - case WGPUBackendType_OpenGL: - print_hub_report(report.gl, "\tgl."); - break; - default: - printf("[framework] frmwrk_print_global_report: invalid backend type: %d", - report.backendType); - } + print_hub_report(report.hub, "\thub."); printf("}\n"); } void frmwrk_print_adapter_info(WGPUAdapter adapter) { struct WGPUAdapterInfo info = {0}; wgpuAdapterGetInfo(adapter, &info); - printf("description: %s\n", info.description); - printf("vendor: %s\n", info.vendor); - printf("architecture: %s\n", info.architecture); - printf("device: %s\n", info.device); + printf("description: %.*s\n", (int) info.description.length, info.description.data); + printf("vendor: %.*s\n", (int) info.vendor.length, info.vendor.data); + printf("architecture: %.*s\n", (int) info.architecture.length, info.architecture.data); + printf("device: %.*s\n", (int) info.device.length, info.device.data); printf("backend type: %u\n", info.backendType); printf("adapter type: %u\n", info.adapterType); printf("vendorID: %x\n", info.vendorID); diff --git a/examples/framework/framework.h b/examples/framework/framework.h index c10084d7..cbde32bf 100644 --- a/examples/framework/framework.h +++ b/examples/framework/framework.h @@ -12,7 +12,7 @@ typedef struct frmwrk_buffer_init_descriptor { WGPU_NULLABLE char const *label; - WGPUBufferUsageFlags usage; + WGPUBufferUsage usage; void *content; size_t content_size; } frmwrk_buffer_init_descriptor; diff --git a/examples/push_constants/CMakeLists.txt b/examples/push_constants/CMakeLists.txt index 2c00ba2e..087cdbf0 100644 --- a/examples/push_constants/CMakeLists.txt +++ b/examples/push_constants/CMakeLists.txt @@ -14,7 +14,7 @@ include_directories(${CMAKE_SOURCE_DIR}/../ffi/webgpu-headers) include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) set(OS_LIBRARIES "-lm -ldl") elseif(APPLE) diff --git a/examples/push_constants/main.c b/examples/push_constants/main.c index 6018eaa8..c1cbaec5 100644 --- a/examples/push_constants/main.c +++ b/examples/push_constants/main.c @@ -8,21 +8,26 @@ #define LOG_PREFIX "[push_constants]" static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *userdata) { + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUAdapter *)userdata = adapter; + UNUSED(userdata2) + *(WGPUAdapter *)userdata1 = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, char const *message, - void *userdata) { + WGPUDevice device, WGPUStringView message, + void *userdata1, void *userdata2) { UNUSED(status) UNUSED(message) - *(WGPUDevice *)userdata = device; + UNUSED(userdata2) + *(WGPUDevice *)userdata1 = device; } -static void handle_buffer_map(WGPUBufferMapAsyncStatus status, void *userdata) { - UNUSED(userdata) +static void handle_buffer_map(WGPUMapAsyncStatus status, + WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata1) + UNUSED(userdata2) printf(LOG_PREFIX " buffer_map status=%#.8x\n", status); } @@ -39,50 +44,41 @@ int main(int argc, char *argv[]) { assert(instance); WGPUAdapter adapter = NULL; - wgpuInstanceRequestAdapter(instance, NULL, handle_request_adapter, - (void *)&adapter); + wgpuInstanceRequestAdapter(instance, NULL, + (const WGPURequestAdapterCallbackInfo){ + .callback = handle_request_adapter, + .userdata1 = &adapter + }); assert(adapter); - WGPUSupportedLimitsExtras supported_limits_extras = { + WGPUNativeLimits supported_limits_extras = { .chain = { - .sType = WGPUSType_SupportedLimitsExtras, - }, - .limits = - { - .maxPushConstantSize = 0, + .sType = WGPUSType_NativeLimits, }, + .maxPushConstantSize = 0, }; - WGPUSupportedLimits supported_limits = { + WGPULimits supported_limits = { .nextInChain = &supported_limits_extras.chain, }; wgpuAdapterGetLimits(adapter, &supported_limits); - WGPURequiredLimitsExtras required_limits_extras = { - .chain = - { - .sType = WGPUSType_RequiredLimitsExtras, - }, - .limits = supported_limits_extras.limits, - }; - WGPURequiredLimits required_limits = { - .nextInChain = &required_limits_extras.chain, - .limits = supported_limits.limits, - }; - WGPUFeatureName requiredFeatures[] = { WGPUNativeFeature_PushConstants, }; WGPUDeviceDescriptor device_desc = { - .label = "compute_device", + .label = {"compute_device", WGPU_STRLEN}, .requiredFeatures = requiredFeatures, .requiredFeatureCount = 1, - .requiredLimits = &required_limits, + .requiredLimits = &supported_limits, }; WGPUDevice device = NULL; - wgpuAdapterRequestDevice(adapter, &device_desc, handle_request_device, - (void *)&device); + wgpuAdapterRequestDevice(adapter, &device_desc, + (const WGPURequestDeviceCallbackInfo){ + .callback = handle_request_device, + .userdata1 = &device + }); assert(device); WGPUQueue queue = wgpuDeviceGetQueue(device); @@ -94,7 +90,7 @@ int main(int argc, char *argv[]) { WGPUBuffer storage_buffer = wgpuDeviceCreateBuffer( device, &(const WGPUBufferDescriptor){ - .label = "storage_buffer", + .label = {"storage_buffer", WGPU_STRLEN}, .usage = WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst | WGPUBufferUsage_CopySrc, .size = numbers_size, @@ -104,7 +100,7 @@ int main(int argc, char *argv[]) { WGPUBuffer staging_buffer = wgpuDeviceCreateBuffer( device, &(const WGPUBufferDescriptor){ - .label = "staging_buffer", + .label = {"staging_buffer", WGPU_STRLEN}, .usage = WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst, .size = numbers_size, .mappedAtCreation = false, @@ -137,7 +133,7 @@ int main(int argc, char *argv[]) { }, }; WGPUBindGroupLayoutDescriptor bind_group_layout_desc = { - .label = "bind_group_layout", + .label = {"bind_group_layout", WGPU_STRLEN}, .nextInChain = NULL, .entryCount = 1, .entries = bind_group_layout_entries, @@ -147,7 +143,7 @@ int main(int argc, char *argv[]) { assert(bind_group_layout); WGPUPipelineLayoutDescriptor pipeline_layout_desc = { - .label = "pipeline_layout", + .label = {"pipeline_layout", WGPU_STRLEN}, .nextInChain = &pipeline_layout_extras.chain, .bindGroupLayouts = &bind_group_layout, .bindGroupLayoutCount = 1, @@ -158,11 +154,11 @@ int main(int argc, char *argv[]) { WGPUComputePipeline compute_pipeline = wgpuDeviceCreateComputePipeline( device, &(const WGPUComputePipelineDescriptor){ - .label = "compute_pipeline", + .label = {"compute_pipeline", WGPU_STRLEN}, .compute = (const WGPUProgrammableStageDescriptor){ .module = shader_module, - .entryPoint = "main", + .entryPoint = {"main", WGPU_STRLEN}, }, .layout = pipeline_layout, }); @@ -170,7 +166,7 @@ int main(int argc, char *argv[]) { WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup( device, &(const WGPUBindGroupDescriptor){ - .label = "bind_group", + .label = {"bind_group", WGPU_STRLEN}, .layout = bind_group_layout, .entryCount = 1, .entries = @@ -187,14 +183,14 @@ int main(int argc, char *argv[]) { WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( device, &(const WGPUCommandEncoderDescriptor){ - .label = "command_encoder", + .label = {"command_encoder", WGPU_STRLEN}, }); assert(command_encoder); WGPUComputePassEncoder compute_pass_encoder = wgpuCommandEncoderBeginComputePass(command_encoder, &(const WGPUComputePassDescriptor){ - .label = "compute_pass", + .label = {"compute_pass", WGPU_STRLEN}, }); assert(compute_pass_encoder); @@ -219,7 +215,7 @@ int main(int argc, char *argv[]) { WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish( command_encoder, &(const WGPUCommandBufferDescriptor){ - .label = "command_buffer", + .label = {"command_buffer", WGPU_STRLEN}, }); assert(command_buffer); @@ -227,7 +223,9 @@ int main(int argc, char *argv[]) { wgpuQueueSubmit(queue, 1, &command_buffer); wgpuBufferMapAsync(staging_buffer, WGPUMapMode_Read, 0, numbers_size, - handle_buffer_map, NULL); + (const WGPUBufferMapCallbackInfo){ + .callback = handle_buffer_map + }); wgpuDevicePoll(device, true, NULL); uint32_t *buf = diff --git a/examples/texture_arrays/CMakeLists.txt b/examples/texture_arrays/CMakeLists.txt index 8f83ce64..2dc9d637 100644 --- a/examples/texture_arrays/CMakeLists.txt +++ b/examples/texture_arrays/CMakeLists.txt @@ -15,7 +15,7 @@ include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) add_definitions(-DGLFW_EXPOSE_NATIVE_WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) add_definitions(-DGLFW_EXPOSE_NATIVE_X11) add_definitions(-DGLFW_EXPOSE_NATIVE_WAYLAND) diff --git a/examples/texture_arrays/main.c b/examples/texture_arrays/main.c index 907355f7..250d69e6 100644 --- a/examples/texture_arrays/main.c +++ b/examples/texture_arrays/main.c @@ -26,25 +26,27 @@ struct demo { }; static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *userdata) { + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata2) if (status == WGPURequestAdapterStatus_Success) { - struct demo *demo = userdata; + struct demo *demo = userdata1; demo->adapter = adapter; } else { - printf(LOG_PREFIX " request_adapter status=%#.8x message=%s\n", status, - message); + printf(LOG_PREFIX " request_adapter status=%#.8x message=%.*s\n", status, + (int) message.length, message.data); } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, char const *message, - void *userdata) { + WGPUDevice device, WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata2) if (status == WGPURequestDeviceStatus_Success) { - struct demo *demo = userdata; + struct demo *demo = userdata1; demo->device = device; } else { - printf(LOG_PREFIX " request_device status=%#.8x message=%s\n", status, - message); + printf(LOG_PREFIX " request_device status=%#.8x message=%.*s\n", status, + (int) message.length, message.data); } } static void handle_glfw_framebuffer_size(GLFWwindow *window, int width, @@ -147,10 +149,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromMetalLayer){ + const WGPUSurfaceSourceMetalLayer){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromMetalLayer, + .sType = WGPUSType_SurfaceSourceMetalLayer, }, .layer = metal_layer, }, @@ -165,10 +167,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromXlibWindow){ + const WGPUSurfaceSourceXlibWindow){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromXlibWindow, + .sType = WGPUSType_SurfaceSourceXlibWindow, }, .display = x11_display, .window = x11_window, @@ -183,11 +185,11 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromWaylandSurface){ + const WGPUSurfaceSourceWaylandSurface){ .chain = (const WGPUChainedStruct){ .sType = - WGPUSType_SurfaceDescriptorFromWaylandSurface, + WGPUSType_SurfaceSourceWaylandSurface, }, .display = wayland_display, .surface = wayland_surface, @@ -203,10 +205,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromWindowsHWND){ + const WGPUSurfaceSourceWindowsHWND){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromWindowsHWND, + .sType = WGPUSType_SurfaceSourceWindowsHWND, }, .hinstance = hinstance, .hwnd = hwnd, @@ -222,22 +224,22 @@ int main(int argc, char *argv[]) { &(const WGPURequestAdapterOptions){ .compatibleSurface = demo.surface, }, - handle_request_adapter, &demo); + (const WGPURequestAdapterCallbackInfo){ + .callback = handle_request_adapter, + .userdata1 = &demo + }); assert(demo.adapter); WGPUSurfaceCapabilities surface_capabilities = {0}; wgpuSurfaceGetCapabilities(demo.surface, demo.adapter, &surface_capabilities); - size_t adapter_feature_count = - wgpuAdapterEnumerateFeatures(demo.adapter, NULL); - WGPUFeatureName *adapter_features = (WGPUFeatureName *)malloc( - sizeof(WGPUFeatureName) * adapter_feature_count); - wgpuAdapterEnumerateFeatures(demo.adapter, adapter_features); + WGPUSupportedFeatures adapter_features = {0}; + wgpuAdapterGetFeatures(demo.adapter, &adapter_features); bool adapter_has_required_features = false; bool adapter_has_optional_features = false; - for (size_t i = 0; i < adapter_feature_count; i++) { - switch ((uint32_t)adapter_features[i]) { + for (size_t i = 0; i < adapter_features.featureCount; i++) { + switch ((uint32_t)adapter_features.features[i]) { case WGPUNativeFeature_TextureBindingArray: adapter_has_required_features = true; break; @@ -248,7 +250,7 @@ int main(int argc, char *argv[]) { } assert( adapter_has_required_features /* Adapter must support WGPUNativeFeature_TextureBindingArray feature for this example */); - free(adapter_features); + wgpuSupportedFeaturesFreeMembers(adapter_features); WGPUFeatureName required_device_features[2] = { (WGPUFeatureName)WGPUNativeFeature_TextureBindingArray, @@ -260,13 +262,15 @@ int main(int argc, char *argv[]) { required_device_feature_count++; } - wgpuAdapterRequestDevice( - demo.adapter, - &(const WGPUDeviceDescriptor){ - .requiredFeatureCount = required_device_feature_count, - .requiredFeatures = required_device_features, - }, - handle_request_device, &demo); + wgpuAdapterRequestDevice(demo.adapter, + &(const WGPUDeviceDescriptor){ + .requiredFeatureCount = required_device_feature_count, + .requiredFeatures = required_device_features, + }, + (const WGPURequestDeviceCallbackInfo){ + .callback = handle_request_device, + .userdata1 = &demo + }); assert(demo.device); WGPUQueue queue = wgpuDeviceGetQueue(demo.device); @@ -364,25 +368,25 @@ int main(int argc, char *argv[]) { WGPUTexture red_texture = wgpuDeviceCreateTexture( demo.device, &(const WGPUTextureDescriptor){ COLOR_TEXTURE_DESCRIPTOR_COMMON_FIELDS, - .label = "red", + .label = {"red", WGPU_STRLEN}, }); assert(red_texture); WGPUTexture green_texture = wgpuDeviceCreateTexture( demo.device, &(const WGPUTextureDescriptor){ COLOR_TEXTURE_DESCRIPTOR_COMMON_FIELDS, - .label = "green", + .label = {"green", WGPU_STRLEN}, }); assert(green_texture); WGPUTexture blue_texture = wgpuDeviceCreateTexture( demo.device, &(const WGPUTextureDescriptor){ COLOR_TEXTURE_DESCRIPTOR_COMMON_FIELDS, - .label = "blue", + .label = {"blue", WGPU_STRLEN}, }); assert(blue_texture); WGPUTexture white_texture = wgpuDeviceCreateTexture( demo.device, &(const WGPUTextureDescriptor){ COLOR_TEXTURE_DESCRIPTOR_COMMON_FIELDS, - .label = "white", + .label = {"white", WGPU_STRLEN}, }); assert(white_texture); @@ -404,36 +408,36 @@ int main(int argc, char *argv[]) { .aspect = WGPUTextureAspect_All /* clang-format on */ - const WGPUTextureDataLayout texture_data_layout_common = - (const WGPUTextureDataLayout){ + const WGPUTexelCopyBufferLayout texture_data_layout_common = + (const WGPUTexelCopyBufferLayout){ .offset = 0, .bytesPerRow = 4, .rowsPerImage = WGPU_COPY_STRIDE_UNDEFINED, }; wgpuQueueWriteTexture(queue, - &(const WGPUImageCopyTexture){ + &(const WGPUTexelCopyTextureInfo){ .texture = red_texture, COLOR_IMAGE_COPY_TEXTURE_COMMON_FIELDS, }, red_texture_data, sizeof(red_texture_data), &texture_data_layout_common, &extent_3d_default); wgpuQueueWriteTexture(queue, - &(const WGPUImageCopyTexture){ + &(const WGPUTexelCopyTextureInfo){ .texture = green_texture, COLOR_IMAGE_COPY_TEXTURE_COMMON_FIELDS, }, green_texture_data, sizeof(green_texture_data), &texture_data_layout_common, &extent_3d_default); wgpuQueueWriteTexture(queue, - &(const WGPUImageCopyTexture){ + &(const WGPUTexelCopyTextureInfo){ .texture = blue_texture, COLOR_IMAGE_COPY_TEXTURE_COMMON_FIELDS, }, blue_texture_data, sizeof(blue_texture_data), &texture_data_layout_common, &extent_3d_default); wgpuQueueWriteTexture(queue, - &(const WGPUImageCopyTexture){ + &(const WGPUTexelCopyTextureInfo){ .texture = white_texture, COLOR_IMAGE_COPY_TEXTURE_COMMON_FIELDS, }, @@ -512,7 +516,7 @@ int main(int argc, char *argv[]) { }; WGPUBindGroupLayout bind_group_layout = wgpuDeviceCreateBindGroupLayout( demo.device, &(const WGPUBindGroupLayoutDescriptor){ - .label = "bind group layout", + .label = {"bind group layout", WGPU_STRLEN}, .entryCount = sizeof(bind_group_layout_entries) / sizeof(bind_group_layout_entries[0]), .entries = bind_group_layout_entries, @@ -578,7 +582,7 @@ int main(int argc, char *argv[]) { WGPUBindGroup bind_group = wgpuDeviceCreateBindGroup( demo.device, &(const WGPUBindGroupDescriptor){ .layout = bind_group_layout, - .label = "bind group", + .label = {"bind group", WGPU_STRLEN}, .entryCount = sizeof(bind_group_entries) / sizeof(bind_group_entries[0]), .entries = bind_group_entries, @@ -587,7 +591,7 @@ int main(int argc, char *argv[]) { WGPUPipelineLayout pipeline_layout = wgpuDeviceCreatePipelineLayout( demo.device, &(const WGPUPipelineLayoutDescriptor){ - .label = "main", + .label = {"main", WGPU_STRLEN}, .bindGroupLayoutCount = 1, .bindGroupLayouts = (const WGPUBindGroupLayout[]){ @@ -603,7 +607,7 @@ int main(int argc, char *argv[]) { .vertex = (const WGPUVertexState){ .module = base_shader_module, - .entryPoint = "vert_main", + .entryPoint = {"vert_main", WGPU_STRLEN}, .bufferCount = 1, .buffers = (const WGPUVertexBufferLayout[]){ @@ -619,7 +623,7 @@ int main(int argc, char *argv[]) { .fragment = &(const WGPUFragmentState){ .module = fragment_shader_module, - .entryPoint = fragment_entry_point, + .entryPoint = {fragment_entry_point, WGPU_STRLEN}, .targetCount = 1, .targets = (const WGPUColorTargetState[]){ @@ -648,8 +652,9 @@ int main(int argc, char *argv[]) { WGPUSurfaceTexture surface_texture; wgpuSurfaceGetCurrentTexture(demo.surface, &surface_texture); switch (surface_texture.status) { - case WGPUSurfaceGetCurrentTextureStatus_Success: - // All good, could check for `surface_texture.suboptimal` here. + case WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal: + case WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal: + // All good, could handle suboptimal here break; case WGPUSurfaceGetCurrentTextureStatus_Timeout: case WGPUSurfaceGetCurrentTextureStatus_Outdated: @@ -683,7 +688,7 @@ int main(int argc, char *argv[]) { WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( demo.device, &(const WGPUCommandEncoderDescriptor){ - .label = "command_encoder", + .label = {"command_encoder", WGPU_STRLEN}, }); assert(command_encoder); @@ -691,7 +696,7 @@ int main(int argc, char *argv[]) { wgpuCommandEncoderBeginRenderPass( command_encoder, &(const WGPURenderPassDescriptor){ - .label = "render_pass_encoder", + .label = {"render_pass_encoder", WGPU_STRLEN}, .colorAttachmentCount = 1, .colorAttachments = (const WGPURenderPassColorAttachment[]){ @@ -735,7 +740,7 @@ int main(int argc, char *argv[]) { WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish( command_encoder, &(const WGPUCommandBufferDescriptor){ - .label = "command_buffer", + .label = {"command_buffer", WGPU_STRLEN}, }); assert(command_buffer); diff --git a/examples/triangle/CMakeLists.txt b/examples/triangle/CMakeLists.txt index 247c2617..b186e8e1 100644 --- a/examples/triangle/CMakeLists.txt +++ b/examples/triangle/CMakeLists.txt @@ -15,7 +15,7 @@ include_directories(${CMAKE_SOURCE_DIR}/framework) if (WIN32) add_definitions(-DGLFW_EXPOSE_NATIVE_WIN32) - set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32) + set(OS_LIBRARIES d3dcompiler ws2_32 userenv bcrypt ntdll opengl32 Propsys RuntimeObject) elseif(UNIX AND NOT APPLE) add_definitions(-DGLFW_EXPOSE_NATIVE_X11) add_definitions(-DGLFW_EXPOSE_NATIVE_WAYLAND) diff --git a/examples/triangle/main.c b/examples/triangle/main.c index fb6eacdd..50d468d8 100644 --- a/examples/triangle/main.c +++ b/examples/triangle/main.c @@ -26,25 +26,27 @@ struct demo { }; static void handle_request_adapter(WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *userdata) { + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata2) if (status == WGPURequestAdapterStatus_Success) { - struct demo *demo = userdata; + struct demo *demo = userdata1; demo->adapter = adapter; } else { - printf(LOG_PREFIX " request_adapter status=%#.8x message=%s\n", status, - message); + printf(LOG_PREFIX " request_adapter status=%#.8x message=%.*s\n", status, + (int) message.length, message.data); } } static void handle_request_device(WGPURequestDeviceStatus status, - WGPUDevice device, char const *message, - void *userdata) { + WGPUDevice device, WGPUStringView message, + void *userdata1, void *userdata2) { + UNUSED(userdata2) if (status == WGPURequestDeviceStatus_Success) { - struct demo *demo = userdata; + struct demo *demo = userdata1; demo->device = device; } else { - printf(LOG_PREFIX " request_device status=%#.8x message=%s\n", status, - message); + printf(LOG_PREFIX " request_device status=%#.8x message=%.*s\n", status, + (int) message.length, message.data); } } static void handle_glfw_key(GLFWwindow *window, int key, int scancode, @@ -110,10 +112,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromMetalLayer){ + const WGPUSurfaceSourceMetalLayer){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromMetalLayer, + .sType = WGPUSType_SurfaceSourceMetalLayer, }, .layer = metal_layer, }, @@ -128,10 +130,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromXlibWindow){ + const WGPUSurfaceSourceXlibWindow){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromXlibWindow, + .sType = WGPUSType_SurfaceSourceXlibWindow, }, .display = x11_display, .window = x11_window, @@ -146,11 +148,11 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromWaylandSurface){ + const WGPUSurfaceSourceWaylandSurface){ .chain = (const WGPUChainedStruct){ .sType = - WGPUSType_SurfaceDescriptorFromWaylandSurface, + WGPUSType_SurfaceSourceWaylandSurface, }, .display = wayland_display, .surface = wayland_surface, @@ -166,10 +168,10 @@ int main(int argc, char *argv[]) { &(const WGPUSurfaceDescriptor){ .nextInChain = (const WGPUChainedStruct *)&( - const WGPUSurfaceDescriptorFromWindowsHWND){ + const WGPUSurfaceSourceWindowsHWND){ .chain = (const WGPUChainedStruct){ - .sType = WGPUSType_SurfaceDescriptorFromWindowsHWND, + .sType = WGPUSType_SurfaceSourceWindowsHWND, }, .hinstance = hinstance, .hwnd = hwnd, @@ -185,12 +187,19 @@ int main(int argc, char *argv[]) { &(const WGPURequestAdapterOptions){ .compatibleSurface = demo.surface, }, - handle_request_adapter, &demo); + (const WGPURequestAdapterCallbackInfo){ + .callback = handle_request_adapter, + .userdata1 = &demo + }); assert(demo.adapter); frmwrk_print_adapter_info(demo.adapter); - wgpuAdapterRequestDevice(demo.adapter, NULL, handle_request_device, &demo); + wgpuAdapterRequestDevice(demo.adapter, NULL, + (const WGPURequestDeviceCallbackInfo){ + .callback = handle_request_device, + .userdata1 = &demo + }); assert(demo.device); WGPUQueue queue = wgpuDeviceGetQueue(demo.device); @@ -202,7 +211,7 @@ int main(int argc, char *argv[]) { WGPUPipelineLayout pipeline_layout = wgpuDeviceCreatePipelineLayout( demo.device, &(const WGPUPipelineLayoutDescriptor){ - .label = "pipeline_layout", + .label = {"pipeline_layout", WGPU_STRLEN}, }); assert(pipeline_layout); @@ -212,17 +221,17 @@ int main(int argc, char *argv[]) { WGPURenderPipeline render_pipeline = wgpuDeviceCreateRenderPipeline( demo.device, &(const WGPURenderPipelineDescriptor){ - .label = "render_pipeline", + .label = {"render_pipeline", WGPU_STRLEN}, .layout = pipeline_layout, .vertex = (const WGPUVertexState){ .module = shader_module, - .entryPoint = "vs_main", + .entryPoint = {"vs_main", WGPU_STRLEN}, }, .fragment = &(const WGPUFragmentState){ .module = shader_module, - .entryPoint = "fs_main", + .entryPoint = {"fs_main", WGPU_STRLEN}, .targetCount = 1, .targets = (const WGPUColorTargetState[]){ @@ -267,8 +276,9 @@ int main(int argc, char *argv[]) { WGPUSurfaceTexture surface_texture; wgpuSurfaceGetCurrentTexture(demo.surface, &surface_texture); switch (surface_texture.status) { - case WGPUSurfaceGetCurrentTextureStatus_Success: - // All good, could check for `surface_texture.suboptimal` here. + case WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal: + case WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal: + // All good, could handle suboptimal here break; case WGPUSurfaceGetCurrentTextureStatus_Timeout: case WGPUSurfaceGetCurrentTextureStatus_Outdated: @@ -302,7 +312,7 @@ int main(int argc, char *argv[]) { WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( demo.device, &(const WGPUCommandEncoderDescriptor){ - .label = "command_encoder", + .label = {"command_encoder", WGPU_STRLEN}, }); assert(command_encoder); @@ -310,7 +320,7 @@ int main(int argc, char *argv[]) { wgpuCommandEncoderBeginRenderPass( command_encoder, &(const WGPURenderPassDescriptor){ - .label = "render_pass_encoder", + .label = {"render_pass_encoder", WGPU_STRLEN}, .colorAttachmentCount = 1, .colorAttachments = (const WGPURenderPassColorAttachment[]){ @@ -338,7 +348,7 @@ int main(int argc, char *argv[]) { WGPUCommandBuffer command_buffer = wgpuCommandEncoderFinish( command_encoder, &(const WGPUCommandBufferDescriptor){ - .label = "command_buffer", + .label = {"command_buffer", WGPU_STRLEN}, }); assert(command_buffer); diff --git a/examples/vendor/glfw b/examples/vendor/glfw index 7b6aead9..b35641f4 160000 --- a/examples/vendor/glfw +++ b/examples/vendor/glfw @@ -1 +1 @@ -Subproject commit 7b6aead9fb88b3623e3b3725ebb42670cbe4c579 +Subproject commit b35641f4a3c62aa86a0b3c983d163bc0fe36026d diff --git a/ffi/webgpu-headers b/ffi/webgpu-headers index 043af6c7..bac52083 160000 --- a/ffi/webgpu-headers +++ b/ffi/webgpu-headers @@ -1 +1 @@ -Subproject commit 043af6c77e566f707db36759d9c9f161ebb616fd +Subproject commit bac520839ff5ed2e2b648ed540bd9ec45edbccbc diff --git a/ffi/wgpu.h b/ffi/wgpu.h index 7c1cf575..fb3aece8 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -6,10 +6,9 @@ typedef enum WGPUNativeSType { // Start at 0003 since that's allocated range for wgpu-native WGPUSType_DeviceExtras = 0x00030001, - WGPUSType_RequiredLimitsExtras = 0x00030002, + WGPUSType_NativeLimits = 0x00030002, WGPUSType_PipelineLayoutExtras = 0x00030003, WGPUSType_ShaderModuleGLSLDescriptor = 0x00030004, - WGPUSType_SupportedLimitsExtras = 0x00030005, WGPUSType_InstanceExtras = 0x00030006, WGPUSType_BindGroupEntryExtras = 0x00030007, WGPUSType_BindGroupLayoutEntryExtras = 0x00030008, @@ -69,30 +68,26 @@ typedef enum WGPULogLevel { WGPULogLevel_Force32 = 0x7FFFFFFF } WGPULogLevel; -typedef enum WGPUInstanceBackend { - WGPUInstanceBackend_All = 0x00000000, - WGPUInstanceBackend_Vulkan = 1 << 0, - WGPUInstanceBackend_GL = 1 << 1, - WGPUInstanceBackend_Metal = 1 << 2, - WGPUInstanceBackend_DX12 = 1 << 3, - WGPUInstanceBackend_DX11 = 1 << 4, - WGPUInstanceBackend_BrowserWebGPU = 1 << 5, - WGPUInstanceBackend_Primary = WGPUInstanceBackend_Vulkan | WGPUInstanceBackend_Metal | - WGPUInstanceBackend_DX12 | - WGPUInstanceBackend_BrowserWebGPU, - WGPUInstanceBackend_Secondary = WGPUInstanceBackend_GL | WGPUInstanceBackend_DX11, - WGPUInstanceBackend_Force32 = 0x7FFFFFFF -} WGPUInstanceBackend; -typedef WGPUFlags WGPUInstanceBackendFlags; - -typedef enum WGPUInstanceFlag { - WGPUInstanceFlag_Default = 0x00000000, - WGPUInstanceFlag_Debug = 1 << 0, - WGPUInstanceFlag_Validation = 1 << 1, - WGPUInstanceFlag_DiscardHalLabels = 1 << 2, - WGPUInstanceFlag_Force32 = 0x7FFFFFFF -} WGPUInstanceFlag; -typedef WGPUFlags WGPUInstanceFlags; +typedef WGPUFlags WGPUInstanceBackend; +static const WGPUInstanceBackend WGPUInstanceBackend_All = 0x00000000; +static const WGPUInstanceBackend WGPUInstanceBackend_Vulkan = 1 << 0; +static const WGPUInstanceBackend WGPUInstanceBackend_GL = 1 << 1; +static const WGPUInstanceBackend WGPUInstanceBackend_Metal = 1 << 2; +static const WGPUInstanceBackend WGPUInstanceBackend_DX12 = 1 << 3; +static const WGPUInstanceBackend WGPUInstanceBackend_DX11 = 1 << 4; +static const WGPUInstanceBackend WGPUInstanceBackend_BrowserWebGPU = 1 << 5; +// Vulkan, Metal, DX12 and BrowserWebGPU +static const WGPUInstanceBackend WGPUInstanceBackend_Primary = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 5); +// GL and DX11 +static const WGPUInstanceBackend WGPUInstanceBackend_Secondary = (1 << 1) | (1 << 4); +static const WGPUInstanceBackend WGPUInstanceBackend_Force32 = 0x7FFFFFFF; + +typedef WGPUFlags WGPUInstanceFlag; +static const WGPUInstanceFlag WGPUInstanceFlag_Default = 0x00000000; +static const WGPUInstanceFlag WGPUInstanceFlag_Debug = 1 << 0; +static const WGPUInstanceFlag WGPUInstanceFlag_Validation = 1 << 1; +static const WGPUInstanceFlag WGPUInstanceFlag_DiscardHalLabels = 1 << 2; +static const WGPUInstanceFlag WGPUInstanceFlag_Force32 = 0x7FFFFFFF; typedef enum WGPUDx12Compiler { WGPUDx12Compiler_Undefined = 0x00000000, @@ -125,36 +120,28 @@ typedef enum WGPUNativeQueryType { typedef struct WGPUInstanceExtras { WGPUChainedStruct chain; - WGPUInstanceBackendFlags backends; - WGPUInstanceFlags flags; + WGPUInstanceBackend backends; + WGPUInstanceFlag flags; WGPUDx12Compiler dx12ShaderCompiler; WGPUGles3MinorVersion gles3MinorVersion; - const char * dxilPath; - const char * dxcPath; + WGPUStringView dxilPath; + WGPUStringView dxcPath; } WGPUInstanceExtras; typedef struct WGPUDeviceExtras { WGPUChainedStruct chain; - const char * tracePath; + WGPUStringView tracePath; } WGPUDeviceExtras; typedef struct WGPUNativeLimits { + /** This struct chain is used as mutable in some places and immutable in others. */ + WGPUChainedStructOut chain; uint32_t maxPushConstantSize; uint32_t maxNonSamplerBindings; } WGPUNativeLimits; -typedef struct WGPURequiredLimitsExtras { - WGPUChainedStruct chain; - WGPUNativeLimits limits; -} WGPURequiredLimitsExtras; - -typedef struct WGPUSupportedLimitsExtras { - WGPUChainedStructOut chain; - WGPUNativeLimits limits; -} WGPUSupportedLimitsExtras; - typedef struct WGPUPushConstantRange { - WGPUShaderStageFlags stages; + WGPUShaderStage stages; uint32_t start; uint32_t end; } WGPUPushConstantRange; @@ -167,26 +154,21 @@ typedef struct WGPUPipelineLayoutExtras { typedef uint64_t WGPUSubmissionIndex; -typedef struct WGPUWrappedSubmissionIndex { - WGPUQueue queue; - WGPUSubmissionIndex submissionIndex; -} WGPUWrappedSubmissionIndex; - typedef struct WGPUShaderDefine { - char const * name; - char const * value; + WGPUStringView name; + WGPUStringView value; } WGPUShaderDefine; typedef struct WGPUShaderModuleGLSLDescriptor { WGPUChainedStruct chain; WGPUShaderStage stage; - char const * code; + WGPUStringView code; uint32_t defineCount; WGPUShaderDefine * defines; } WGPUShaderModuleGLSLDescriptor; typedef struct WGPUShaderModuleDescriptorSpirV { - char const * label; + WGPUStringView label; uint32_t sourceSize; uint32_t const * source; } WGPUShaderModuleDescriptorSpirV; @@ -195,7 +177,6 @@ typedef struct WGPURegistryReport { size_t numAllocated; size_t numKeptFromUser; size_t numReleasedFromUser; - size_t numError; size_t elementSize; } WGPURegistryReport; @@ -211,6 +192,7 @@ typedef struct WGPUHubReport { WGPURegistryReport renderBundles; WGPURegistryReport renderPipelines; WGPURegistryReport computePipelines; + WGPURegistryReport pipelineCaches; WGPURegistryReport querySets; WGPURegistryReport buffers; WGPURegistryReport textures; @@ -220,16 +202,12 @@ typedef struct WGPUHubReport { typedef struct WGPUGlobalReport { WGPURegistryReport surfaces; - WGPUBackendType backendType; - WGPUHubReport vulkan; - WGPUHubReport metal; - WGPUHubReport dx12; - WGPUHubReport gl; + WGPUHubReport hub; } WGPUGlobalReport; typedef struct WGPUInstanceEnumerateAdapterOptions { WGPUChainedStruct const * nextInChain; - WGPUInstanceBackendFlags backends; + WGPUInstanceBackend backends; } WGPUInstanceEnumerateAdapterOptions; typedef struct WGPUBindGroupEntryExtras { @@ -258,7 +236,7 @@ typedef struct WGPUSurfaceConfigurationExtras { uint32_t desiredMaximumFrameLatency; } WGPUSurfaceConfigurationExtras WGPU_STRUCTURE_ATTRIBUTE; -typedef void (*WGPULogCallback)(WGPULogLevel level, char const * message, void * userdata); +typedef void (*WGPULogCallback)(WGPULogLevel level, WGPUStringView message, void * userdata); typedef enum WGPUNativeTextureFormat { // From Features::TEXTURE_FORMAT_16BIT_NORM @@ -282,7 +260,7 @@ size_t wgpuInstanceEnumerateAdapters(WGPUInstance instance, WGPU_NULLABLE WGPUIn WGPUSubmissionIndex wgpuQueueSubmitForIndex(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands); // Returns true if the queue is empty, or false if there are more queue submissions still in flight. -WGPUBool wgpuDevicePoll(WGPUDevice device, WGPUBool wait, WGPU_NULLABLE WGPUWrappedSubmissionIndex const * wrappedSubmissionIndex); +WGPUBool wgpuDevicePoll(WGPUDevice device, WGPUBool wait, WGPU_NULLABLE WGPUSubmissionIndex const * wrappedSubmissionIndex); WGPUShaderModule wgpuDeviceCreateShaderModuleSpirV(WGPUDevice device, WGPUShaderModuleDescriptorSpirV const * descriptor); void wgpuSetLogCallback(WGPULogCallback callback, void * userdata); @@ -291,7 +269,7 @@ void wgpuSetLogLevel(WGPULogLevel level); uint32_t wgpuGetVersion(void); -void wgpuRenderPassEncoderSetPushConstants(WGPURenderPassEncoder encoder, WGPUShaderStageFlags stages, uint32_t offset, uint32_t sizeBytes, void const * data); +void wgpuRenderPassEncoderSetPushConstants(WGPURenderPassEncoder encoder, WGPUShaderStage stages, uint32_t offset, uint32_t sizeBytes, void const * data); void wgpuComputePassEncoderSetPushConstants(WGPUComputePassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const * data); void wgpuRenderPassEncoderMultiDrawIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); diff --git a/src/conv.rs b/src/conv.rs index 21f4a7fb..3cf310c5 100644 --- a/src/conv.rs +++ b/src/conv.rs @@ -1,9 +1,10 @@ -use crate::utils::{make_slice, ptr_into_label, ptr_into_pathbuf}; -use crate::{follow_chain, map_enum}; +use crate::utils::{make_slice, string_view_into_label, string_view_into_str}; +use crate::{follow_chain, map_enum, map_enum_with_undefined, new_userdata}; use crate::{native, UncapturedErrorCallback}; +use std::borrow::Cow; use std::num::{NonZeroIsize, NonZeroU32, NonZeroU64}; +use std::path::PathBuf; use std::ptr::NonNull; -use std::{borrow::Cow, ffi::CStr}; map_enum!(map_load_op, WGPULoadOp, wgc::command::LoadOp, Clear, Load); map_enum!( @@ -13,7 +14,7 @@ map_enum!( Discard, Store ); -map_enum!( +map_enum_with_undefined!( map_address_mode, WGPUAddressMode, wgt::AddressMode, @@ -22,7 +23,7 @@ map_enum!( Repeat, MirrorRepeat ); -map_enum!( +map_enum_with_undefined!( map_filter_mode, WGPUFilterMode, wgt::FilterMode, @@ -30,7 +31,7 @@ map_enum!( Nearest, Linear ); -map_enum!( +map_enum_with_undefined!( map_mipmap_filter_mode, WGPUMipmapFilterMode, wgt::FilterMode, @@ -38,7 +39,7 @@ map_enum!( Nearest, Linear ); -map_enum!( +map_enum_with_undefined!( map_compare_function, WGPUCompareFunction, wgt::CompareFunction, @@ -51,7 +52,7 @@ map_enum!( GreaterEqual, Always ); -map_enum!( +map_enum_with_undefined!( map_texture_aspect, WGPUTextureAspect, wgt::TextureAspect, @@ -60,7 +61,7 @@ map_enum!( StencilOnly, DepthOnly ); -map_enum!( +map_enum_with_undefined!( map_present_mode, WGPUPresentMode, wgt::PresentMode, @@ -70,7 +71,7 @@ map_enum!( Fifo, FifoRelaxed ); -map_enum!( +map_enum_with_undefined!( map_primitive_topology, WGPUPrimitiveTopology, wgt::PrimitiveTopology, @@ -88,26 +89,30 @@ map_enum!( Uint16, Uint32 ); -map_enum!( +map_enum_with_undefined!( map_blend_factor, WGPUBlendFactor, wgt::BlendFactor, "Unknown blend factor", - Zero: Zero, - One: One, - Src: Src, - OneMinusSrc: OneMinusSrc, - SrcAlpha: SrcAlpha, - OneMinusSrcAlpha: OneMinusSrcAlpha, - Dst: Dst, - OneMinusDst: OneMinusDst, - DstAlpha: DstAlpha, - OneMinusDstAlpha: OneMinusDstAlpha, - SrcAlphaSaturated: SrcAlphaSaturated, - Constant: Constant, - OneMinusConstant: OneMinusConstant + Zero, + One, + Src, + OneMinusSrc, + SrcAlpha, + OneMinusSrcAlpha, + Dst, + OneMinusDst, + DstAlpha, + OneMinusDstAlpha, + SrcAlphaSaturated, + Constant, + OneMinusConstant, + Src1, + OneMinusSrc1, + Src1Alpha, + OneMinusSrc1Alpha ); -map_enum!( +map_enum_with_undefined!( map_blend_operation, WGPUBlendOperation, wgt::BlendOperation, @@ -118,10 +123,11 @@ map_enum!( Min, Max ); -map_enum!( +map_enum_with_undefined!( map_stencil_operation, WGPUStencilOperation, wgt::StencilOperation, + "Unknown stencil operation", Keep, Zero, Replace, @@ -164,7 +170,8 @@ map_enum!( Sint32, Sint32x2, Sint32x3, - Sint32x4 + Sint32x4, + Unorm10_10_10_2 ); #[cfg(feature = "glsl")] @@ -199,20 +206,23 @@ map_enum!( Version2 ); -map_enum!( +map_enum_with_undefined!( map_storage_texture_access, WGPUStorageTextureAccess, wgt::StorageTextureAccess, + "Unknown storage texture access", WriteOnly, ReadOnly, ReadWrite ); -pub const WGPU_WHOLE_SIZE: ::std::os::raw::c_ulonglong = native::WGPU_WHOLE_SIZE as _; -pub const WGPU_LIMIT_U64_UNDEFINED: ::std::os::raw::c_ulonglong = - native::WGPU_LIMIT_U64_UNDEFINED as _; +// These are defined as UINT64_MAX in the header, but bindgen currently can't process that define. +// See https://github.com/rust-lang/rust-bindgen/issues/2822 +pub const WGPU_WHOLE_SIZE: u64 = u64::MAX; +pub const WGPU_LIMIT_U64_UNDEFINED: u64 = u64::MAX; // it's SIZE_MAX in headers but it's not available in some compilers pub const WGPU_WHOLE_MAP_SIZE: usize = usize::MAX; +pub const WGPU_STRLEN: usize = usize::MAX; #[inline] pub fn map_extent3d(native: &native::WGPUExtent3D) -> wgt::Extent3d { @@ -273,7 +283,7 @@ pub fn map_instance_flags(flags: native::WGPUInstanceFlag) -> wgt::InstanceFlags } #[inline] -pub fn map_instance_descriptor( +pub unsafe fn map_instance_descriptor( _base: &native::WGPUInstanceDescriptor, extras: Option<&native::WGPUInstanceExtras>, ) -> wgt::InstanceDescriptor { @@ -281,8 +291,8 @@ pub fn map_instance_descriptor( let dx12_shader_compiler = match extras.dx12ShaderCompiler { native::WGPUDx12Compiler_Fxc => wgt::Dx12Compiler::Fxc, native::WGPUDx12Compiler_Dxc => wgt::Dx12Compiler::Dxc { - dxil_path: ptr_into_pathbuf(extras.dxilPath), - dxc_path: ptr_into_pathbuf(extras.dxcPath), + dxil_path: string_view_into_str(extras.dxilPath).map(PathBuf::from), + dxc_path: string_view_into_str(extras.dxcPath).map(PathBuf::from), }, _ => wgt::Dx12Compiler::default(), }; @@ -291,7 +301,7 @@ pub fn map_instance_descriptor( backends: map_instance_backend_flags(extras.backends as native::WGPUInstanceBackend), dx12_shader_compiler, gles_minor_version: map_gles3_minor_version(extras.gles3MinorVersion), - flags: match extras.flags as native::WGPUInstanceFlag { + flags: match extras.flags { native::WGPUInstanceFlag_Default => wgt::InstanceFlags::default(), flags => map_instance_flags(flags), }, @@ -302,18 +312,18 @@ pub fn map_instance_descriptor( } #[inline] -pub(crate) fn map_device_descriptor<'a>( +pub(crate) unsafe fn map_device_descriptor<'a>( des: &native::WGPUDeviceDescriptor, base_limits: wgt::Limits, extras: Option<&native::WGPUDeviceExtras>, ) -> ( wgt::DeviceDescriptor>, - *const std::ffi::c_char, + Option<&'a str>, Option, ) { ( wgt::DeviceDescriptor { - label: ptr_into_label(des.label), + label: string_view_into_label(des.label), required_features: map_features(make_slice( des.requiredFeatures, des.requiredFeatureCount, @@ -322,7 +332,7 @@ pub(crate) fn map_device_descriptor<'a>( Some(required_limits) => unsafe { follow_chain!( map_required_limits((required_limits, base_limits), - WGPUSType_RequiredLimitsExtras => native::WGPURequiredLimitsExtras) + WGPUSType_NativeLimits => native::WGPUNativeLimits) ) }, None => base_limits, @@ -330,15 +340,12 @@ pub(crate) fn map_device_descriptor<'a>( // TODO(wgpu.h) memory_hints: Default::default(), }, - match extras { - Some(extras) => extras.tracePath, - None => std::ptr::null(), - }, + extras.and_then(|extras| string_view_into_str(extras.tracePath)), match des.uncapturedErrorCallbackInfo.callback { None => None, callback => Some(UncapturedErrorCallback { callback, - userdata: des.uncapturedErrorCallbackInfo.userdata, + userdata: new_userdata!(des.uncapturedErrorCallbackInfo), }), }, ) @@ -363,7 +370,7 @@ pub unsafe fn map_pipeline_layout_descriptor<'a>( make_slice(extras.pushConstantRanges, extras.pushConstantRangeCount) .iter() .map(|range| wgt::PushConstantRange { - stages: wgt::ShaderStages::from_bits(range.stages) + stages: from_u64_bits(range.stages) .expect("invalid shader stage for push constant range"), range: range.start..range.end, }) @@ -371,18 +378,14 @@ pub unsafe fn map_pipeline_layout_descriptor<'a>( }); return wgc::binding_model::PipelineLayoutDescriptor { - label: ptr_into_label(des.label), + label: string_view_into_label(des.label), bind_group_layouts: Cow::from(bind_group_layouts), push_constant_ranges: Cow::from(push_constant_ranges), }; } #[inline] -pub fn write_limits_struct( - wgt_limits: wgt::Limits, - supported_limits: &mut native::WGPUSupportedLimits, -) { - let mut limits = supported_limits.limits; +pub fn write_limits_struct(wgt_limits: wgt::Limits, limits: &mut native::WGPULimits) { limits.maxTextureDimension1D = wgt_limits.max_texture_dimension_1d; limits.maxTextureDimension2D = wgt_limits.max_texture_dimension_2d; limits.maxTextureDimension3D = wgt_limits.max_texture_dimension_3d; @@ -408,7 +411,6 @@ pub fn write_limits_struct( limits.maxVertexBufferArrayStride = wgt_limits.max_vertex_buffer_array_stride; limits.minUniformBufferOffsetAlignment = wgt_limits.min_uniform_buffer_offset_alignment; limits.minStorageBufferOffsetAlignment = wgt_limits.min_storage_buffer_offset_alignment; - limits.maxInterStageShaderComponents = wgt_limits.max_inter_stage_shader_components; // TODO: not yet in wgt // limits.maxInterStageShaderVariables = wgt_limits.max_inter_stage_shader_variables; // TODO: not yet in wgt @@ -421,33 +423,29 @@ pub fn write_limits_struct( limits.maxComputeWorkgroupSizeY = wgt_limits.max_compute_workgroup_size_y; limits.maxComputeWorkgroupSizeZ = wgt_limits.max_compute_workgroup_size_z; limits.maxComputeWorkgroupsPerDimension = wgt_limits.max_compute_workgroups_per_dimension; - supported_limits.limits = limits; if let Some(native::WGPUChainedStructOut { - sType: native::WGPUSType_SupportedLimitsExtras, + sType: native::WGPUSType_NativeLimits, .. - }) = unsafe { supported_limits.nextInChain.as_ref() } + }) = unsafe { limits.nextInChain.as_ref() } { unsafe { - let extras = std::mem::transmute::< + let native_limits = std::mem::transmute::< *mut native::WGPUChainedStructOut, - *mut native::WGPUSupportedLimitsExtras, - >(supported_limits.nextInChain); - (*extras).limits = native::WGPUNativeLimits { - maxPushConstantSize: wgt_limits.max_push_constant_size, - maxNonSamplerBindings: wgt_limits.max_non_sampler_bindings, - }; + *mut native::WGPUNativeLimits, + >(limits.nextInChain); + (*native_limits).maxPushConstantSize = wgt_limits.max_push_constant_size; + (*native_limits).maxNonSamplerBindings = wgt_limits.max_non_sampler_bindings; } }; } #[inline] pub fn map_required_limits( - required_limits: &native::WGPURequiredLimits, + limits: &native::WGPULimits, base_limits: wgt::Limits, - extras: Option<&native::WGPURequiredLimitsExtras>, + extras: Option<&native::WGPUNativeLimits>, ) -> wgt::Limits { - let limits = required_limits.limits; let mut wgt_limits = base_limits; if limits.maxTextureDimension1D != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_texture_dimension_1d = limits.maxTextureDimension1D; @@ -494,10 +492,10 @@ pub fn map_required_limits( if limits.maxUniformBuffersPerShaderStage != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_uniform_buffers_per_shader_stage = limits.maxUniformBuffersPerShaderStage; } - if limits.maxUniformBufferBindingSize != native::WGPU_LIMIT_U64_UNDEFINED as u64 { + if limits.maxUniformBufferBindingSize != WGPU_LIMIT_U64_UNDEFINED { wgt_limits.max_uniform_buffer_binding_size = limits.maxUniformBufferBindingSize as u32; } - if limits.maxStorageBufferBindingSize != native::WGPU_LIMIT_U64_UNDEFINED as u64 { + if limits.maxStorageBufferBindingSize != WGPU_LIMIT_U64_UNDEFINED { wgt_limits.max_storage_buffer_binding_size = limits.maxStorageBufferBindingSize as u32; } if limits.minUniformBufferOffsetAlignment != native::WGPU_LIMIT_U32_UNDEFINED { @@ -509,7 +507,7 @@ pub fn map_required_limits( if limits.maxVertexBuffers != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_vertex_buffers = limits.maxVertexBuffers; } - if limits.maxBufferSize != native::WGPU_LIMIT_U64_UNDEFINED as u64 { + if limits.maxBufferSize != WGPU_LIMIT_U64_UNDEFINED { wgt_limits.max_buffer_size = limits.maxBufferSize; } if limits.maxVertexAttributes != native::WGPU_LIMIT_U32_UNDEFINED { @@ -518,9 +516,6 @@ pub fn map_required_limits( if limits.maxVertexBufferArrayStride != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_vertex_buffer_array_stride = limits.maxVertexBufferArrayStride; } - if limits.maxInterStageShaderComponents != native::WGPU_LIMIT_U32_UNDEFINED { - wgt_limits.max_inter_stage_shader_components = limits.maxInterStageShaderComponents; - } // TODO: not yet in wgt // if limits.maxInterStageShaderVariables != native::WGPU_LIMIT_U32_UNDEFINED { // wgt_limits.max_inter_stage_shader_variables = limits.maxInterStageShaderVariables; @@ -551,8 +546,7 @@ pub fn map_required_limits( if limits.maxComputeWorkgroupsPerDimension != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension; } - if let Some(extras) = extras { - let limits = extras.limits; + if let Some(limits) = extras { if limits.maxPushConstantSize != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_push_constant_size = limits.maxPushConstantSize; } @@ -574,16 +568,15 @@ pub enum ShaderParseError { } #[inline] -pub fn map_shader_module<'a>( +pub unsafe fn map_shader_module<'a>( _: &native::WGPUShaderModuleDescriptor, - spirv: Option<&native::WGPUShaderModuleSPIRVDescriptor>, - wgsl: Option<&native::WGPUShaderModuleWGSLDescriptor>, + spirv: Option<&native::WGPUShaderSourceSPIRV>, + wgsl: Option<&native::WGPUShaderSourceWGSL>, glsl: Option<&native::WGPUShaderModuleGLSLDescriptor>, ) -> Result, ShaderParseError> { #[cfg(feature = "wgsl")] if let Some(wgsl) = wgsl { - let c_str: &CStr = unsafe { CStr::from_ptr(wgsl.code) }; - let str_slice: &str = c_str.to_str().expect("not a valid utf-8 string"); + let str_slice: &str = string_view_into_str(wgsl.code).unwrap_or(""); return Ok(wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Borrowed( str_slice, ))); @@ -607,8 +600,7 @@ pub fn map_shader_module<'a>( #[cfg(feature = "glsl")] if let Some(glsl) = glsl { - let c_str: &CStr = unsafe { CStr::from_ptr(glsl.code) }; - let str_slice: &str = c_str.to_str().expect("not a valid utf-8 string"); + let str_slice: &str = string_view_into_str(glsl.code).unwrap_or(""); let mut options = naga::front::glsl::Options::from( map_shader_stage(glsl.stage) .expect("invalid shader stage for shader module glsl descriptor"), @@ -616,11 +608,8 @@ pub fn map_shader_module<'a>( let raw_defines = make_slice(glsl.defines, glsl.defineCount as usize); for define in raw_defines { - let name_c_str: &CStr = unsafe { CStr::from_ptr(define.name) }; - let name_str_slice: &str = name_c_str.to_str().expect("not a valid utf-8 string"); - - let value_c_str: &CStr = unsafe { CStr::from_ptr(define.value) }; - let value_str_slice: &str = value_c_str.to_str().expect("not a valid utf-8 string"); + let name_str_slice: &str = string_view_into_str(define.name).unwrap_or(""); + let value_str_slice: &str = string_view_into_str(define.value).unwrap_or(""); options .defines @@ -639,7 +628,7 @@ pub fn map_shader_module<'a>( #[inline] pub unsafe fn map_image_copy_texture( - native: &native::WGPUImageCopyTexture, + native: &native::WGPUTexelCopyTextureInfo, ) -> wgc::command::ImageCopyTexture { wgt::ImageCopyTexture { texture: native @@ -649,13 +638,13 @@ pub unsafe fn map_image_copy_texture( .id, mip_level: native.mipLevel, origin: map_origin3d(&native.origin), - aspect: map_texture_aspect(native.aspect), + aspect: map_texture_aspect(native.aspect).unwrap_or(wgt::TextureAspect::All), } } #[inline] pub unsafe fn map_image_copy_buffer( - native: &native::WGPUImageCopyBuffer, + native: &native::WGPUTexelCopyBufferInfo, ) -> wgc::command::ImageCopyBuffer { wgt::ImageCopyBuffer { buffer: native @@ -668,7 +657,7 @@ pub unsafe fn map_image_copy_buffer( } #[inline] -pub fn map_texture_data_layout(native: &native::WGPUTextureDataLayout) -> wgt::ImageDataLayout { +pub fn map_texture_data_layout(native: &native::WGPUTexelCopyBufferLayout) -> wgt::ImageDataLayout { wgt::ImageDataLayout { offset: native.offset, bytes_per_row: match native.bytesPerRow { @@ -697,9 +686,9 @@ pub fn map_color(native: &native::WGPUColor) -> wgt::Color { #[inline] pub fn map_blend_component(native: native::WGPUBlendComponent) -> wgt::BlendComponent { wgt::BlendComponent { - src_factor: map_blend_factor(native.srcFactor), - dst_factor: map_blend_factor(native.dstFactor), - operation: map_blend_operation(native.operation), + src_factor: map_blend_factor(native.srcFactor).unwrap_or(wgt::BlendFactor::One), + dst_factor: map_blend_factor(native.dstFactor).unwrap_or(wgt::BlendFactor::Zero), + operation: map_blend_operation(native.operation).unwrap_or(wgt::BlendOperation::Add), } } @@ -707,6 +696,8 @@ pub fn map_blend_component(native: native::WGPUBlendComponent) -> wgt::BlendComp pub fn map_texture_view_dimension( value: native::WGPUTextureViewDimension, ) -> Option { + // This doesn't use map_enum_with_undefined! because the enum name after the _ + // isn't a valid ident on its own for the macro. match value { native::WGPUTextureViewDimension_1D => Some(wgt::TextureViewDimension::D1), native::WGPUTextureViewDimension_2D => Some(wgt::TextureViewDimension::D2), @@ -714,16 +705,20 @@ pub fn map_texture_view_dimension( native::WGPUTextureViewDimension_Cube => Some(wgt::TextureViewDimension::Cube), native::WGPUTextureViewDimension_CubeArray => Some(wgt::TextureViewDimension::CubeArray), native::WGPUTextureViewDimension_3D => Some(wgt::TextureViewDimension::D3), - _ => None, + native::WGPUTextureDimension_Undefined => None, + _ => panic!("Unknown texture view dimension"), } } #[inline] -pub fn map_texture_dimension(value: native::WGPUTextureDimension) -> wgt::TextureDimension { +pub fn map_texture_dimension(value: native::WGPUTextureDimension) -> Option { + // This doesn't use map_enum_with_undefined! because the enum name after the _ + // isn't a valid ident on its own for the macro. match value { - native::WGPUTextureDimension_1D => wgt::TextureDimension::D1, - native::WGPUTextureDimension_2D => wgt::TextureDimension::D2, - native::WGPUTextureDimension_3D => wgt::TextureDimension::D3, + native::WGPUTextureDimension_1D => Some(wgt::TextureDimension::D1), + native::WGPUTextureDimension_2D => Some(wgt::TextureDimension::D2), + native::WGPUTextureDimension_3D => Some(wgt::TextureDimension::D3), + native::WGPUTextureDimension_Undefined => None, x => panic!("Unknown texture dimension: {x}"), } } @@ -734,6 +729,7 @@ pub fn map_texture_format(value: native::WGPUTextureFormat) -> Option None, native::WGPUTextureFormat_R8Unorm => Some(wgt::TextureFormat::R8Unorm), native::WGPUTextureFormat_R8Snorm => Some(wgt::TextureFormat::R8Snorm), native::WGPUTextureFormat_R8Uint => Some(wgt::TextureFormat::R8Uint), @@ -760,7 +756,7 @@ pub fn map_texture_format(value: native::WGPUTextureFormat) -> Option Some(wgt::TextureFormat::Bgra8UnormSrgb), native::WGPUTextureFormat_RGB10A2Uint => Some(wgt::TextureFormat::Rgb10a2Uint), native::WGPUTextureFormat_RGB10A2Unorm => Some(wgt::TextureFormat::Rgb10a2Unorm), - native::WGPUTextureFormat_RG11B10Ufloat => Some(wgt::TextureFormat::Rg11b10Float), + native::WGPUTextureFormat_RG11B10Ufloat => Some(wgt::TextureFormat::Rg11b10Ufloat), native::WGPUTextureFormat_RGB9E5Ufloat => Some(wgt::TextureFormat::Rgb9e5Ufloat), native::WGPUTextureFormat_RG32Float => Some(wgt::TextureFormat::Rg32Float), native::WGPUTextureFormat_RG32Uint => Some(wgt::TextureFormat::Rg32Uint), @@ -838,7 +834,7 @@ pub fn map_texture_format(value: native::WGPUTextureFormat) -> Option Some(wgt::TextureFormat::Rgba16Unorm), native::WGPUNativeTextureFormat_Rgba16Snorm => Some(wgt::TextureFormat::Rgba16Snorm), native::WGPUNativeTextureFormat_NV12 => Some(wgt::TextureFormat::NV12), - _ => None, + _ => panic!("Unknown texture format"), } } @@ -877,7 +873,7 @@ pub fn to_native_texture_format(rs_type: wgt::TextureFormat) -> Option Some(native::WGPUTextureFormat_BGRA8UnormSrgb), wgt::TextureFormat::Rgb10a2Uint => Some(native::WGPUTextureFormat_RGB10A2Uint), wgt::TextureFormat::Rgb10a2Unorm => Some(native::WGPUTextureFormat_RGB10A2Unorm), - wgt::TextureFormat::Rg11b10Float => Some(native::WGPUTextureFormat_RG11B10Ufloat), + wgt::TextureFormat::Rg11b10Ufloat => Some(native::WGPUTextureFormat_RG11B10Ufloat), wgt::TextureFormat::Rgb9e5Ufloat => Some(native::WGPUTextureFormat_RGB9E5Ufloat), wgt::TextureFormat::Rg32Float => Some(native::WGPUTextureFormat_RG32Float), wgt::TextureFormat::Rg32Uint => Some(native::WGPUTextureFormat_RG32Uint), @@ -965,26 +961,13 @@ pub fn map_stencil_face_state( ) -> wgt::StencilFaceState { wgt::StencilFaceState { compare: map_compare_function(value.compare) - .unwrap_or_else(|_| panic!("invalid compare function for {mode} stencil face state")), - fail_op: map_stencil_operation(value.failOp) - .unwrap_or_else(|_| panic!("invalid fail op for {mode} stencil face state")), + .unwrap_or_else(|_| panic!("invalid compare function for {mode} stencil face state")) + .unwrap_or(wgt::CompareFunction::Always), + fail_op: map_stencil_operation(value.failOp).unwrap_or(wgt::StencilOperation::Keep), depth_fail_op: map_stencil_operation(value.depthFailOp) - .unwrap_or_else(|_| panic!("invalid depth fail op for {mode} stencil face state")), - pass_op: map_stencil_operation(value.passOp) - .unwrap_or_else(|_| panic!("invalid pass op for {mode} stencil face state")), - } -} - -#[inline] -pub fn map_primitive_state( - _: &native::WGPUPrimitiveState, - depth_clip_control: Option<&native::WGPUPrimitiveDepthClipControl>, -) -> bool { - if let Some(depth_clip_control) = depth_clip_control { - return depth_clip_control.unclippedDepth != 0; + .unwrap_or(wgt::StencilOperation::Keep), + pass_op: map_stencil_operation(value.passOp).unwrap_or(wgt::StencilOperation::Keep), } - - false } #[inline] @@ -993,7 +976,6 @@ pub fn map_storage_report(report: &wgc::registry::RegistryReport) -> native::WGP numAllocated: report.num_allocated, numKeptFromUser: report.num_kept_from_user, numReleasedFromUser: report.num_released_from_user, - numError: report.num_error, elementSize: report.element_size, } } @@ -1012,6 +994,7 @@ pub fn map_hub_report(report: &wgc::hub::HubReport) -> native::WGPUHubReport { renderBundles: map_storage_report(&report.render_bundles), renderPipelines: map_storage_report(&report.render_pipelines), computePipelines: map_storage_report(&report.compute_pipelines), + pipelineCaches: map_storage_report(&report.pipeline_caches), querySets: map_storage_report(&report.query_sets), buffers: map_storage_report(&report.buffers), textures: map_storage_report(&report.textures), @@ -1026,41 +1009,7 @@ pub fn write_global_report( report: &wgc::global::GlobalReport, ) { native_report.surfaces = map_storage_report(&report.surfaces); - - #[cfg(any( - all( - any(target_os = "ios", target_os = "macos"), - feature = "vulkan-portability" - ), - windows, - all(unix, not(target_os = "ios"), not(target_os = "macos")) - ))] - if let Some(ref vulkan) = report.vulkan { - native_report.vulkan = map_hub_report(vulkan); - native_report.backendType = native::WGPUBackendType_Vulkan; - } - - #[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))] - if let Some(ref metal) = report.metal { - native_report.metal = map_hub_report(metal); - native_report.backendType = native::WGPUBackendType_Metal; - } - - #[cfg(all(target_os = "windows", feature = "dx12"))] - if let Some(ref dx12) = report.dx12 { - native_report.dx12 = map_hub_report(dx12); - native_report.backendType = native::WGPUBackendType_D3D12; - } - - #[cfg(any( - feature = "angle", - target_os = "windows", - all(unix, not(target_os = "ios"), not(target_os = "macos")) - ))] - if let Some(ref gl) = report.gl { - native_report.gl = map_hub_report(gl); - native_report.backendType = native::WGPUBackendType_OpenGL; - } + native_report.hub = map_hub_report(&report.hub); } #[inline] @@ -1113,7 +1062,9 @@ pub fn features_to_native(features: wgt::Features) -> Vec Option { native::WGPUFeatureName_DepthClipControl => Some(Features::DEPTH_CLIP_CONTROL), native::WGPUFeatureName_Depth32FloatStencil8 => Some(Features::DEPTH32FLOAT_STENCIL8), native::WGPUFeatureName_TextureCompressionBC => Some(Features::TEXTURE_COMPRESSION_BC), + // TODO: WGPUFeatureName_TextureCompressionBCSliced3D native::WGPUFeatureName_TextureCompressionETC2 => Some(Features::TEXTURE_COMPRESSION_ETC2), native::WGPUFeatureName_TextureCompressionASTC => Some(Features::TEXTURE_COMPRESSION_ASTC), + // TODO: WGPUFeatureName_TextureCompressionASTCSliced3D native::WGPUFeatureName_TimestampQuery => Some(Features::TIMESTAMP_QUERY), native::WGPUFeatureName_IndirectFirstInstance => Some(Features::INDIRECT_FIRST_INSTANCE), native::WGPUFeatureName_ShaderF16 => Some(Features::SHADER_F16), native::WGPUFeatureName_RG11B10UfloatRenderable => Some(Features::RG11B10UFLOAT_RENDERABLE), native::WGPUFeatureName_BGRA8UnormStorage => Some(Features::BGRA8UNORM_STORAGE), + // TODO: WGPUFeatureName_ClipDistances + // TODO: WGPUFeatureName_Float32Blendable native::WGPUFeatureName_Float32Filterable => Some(Features::FLOAT32_FILTERABLE), + native::WGPUFeatureName_DualSourceBlending => Some(Features::DUAL_SOURCE_BLENDING), // wgpu-rs only features native::WGPUNativeFeature_PushConstants => Some(Features::PUSH_CONSTANTS), @@ -1399,16 +1355,16 @@ pub fn map_bind_group_layout_entry( entry: &native::WGPUBindGroupLayoutEntry, extras: Option<&native::WGPUBindGroupLayoutEntryExtras>, ) -> wgt::BindGroupLayoutEntry { - let is_buffer = entry.buffer.type_ != native::WGPUBufferBindingType_Undefined; - let is_sampler = entry.sampler.type_ != native::WGPUSamplerBindingType_Undefined; - let is_texture = entry.texture.sampleType != native::WGPUTextureSampleType_Undefined; + let is_buffer = entry.buffer.type_ != native::WGPUBufferBindingType_BindingNotUsed; + let is_sampler = entry.sampler.type_ != native::WGPUSamplerBindingType_BindingNotUsed; + let is_texture = entry.texture.sampleType != native::WGPUTextureSampleType_BindingNotUsed; let is_storage_texture = - entry.storageTexture.access != native::WGPUStorageTextureAccess_Undefined; + entry.storageTexture.access != native::WGPUStorageTextureAccess_BindingNotUsed; let ty = if is_texture { wgt::BindingType::Texture { sample_type: match entry.texture.sampleType { - native::WGPUTextureSampleType_Float => { + native::WGPUTextureSampleType_Float | native::WGPUTextureSampleType_Undefined => { wgt::TextureSampleType::Float { filterable: true } } native::WGPUTextureSampleType_UnfilterableFloat => { @@ -1432,7 +1388,7 @@ pub fn map_bind_group_layout_entry( } } else if is_sampler { match entry.sampler.type_ { - native::WGPUSamplerBindingType_Filtering => { + native::WGPUSamplerBindingType_Filtering | native::WGPUSamplerBindingType_Undefined => { wgt::BindingType::Sampler(wgt::SamplerBindingType::Filtering) } native::WGPUSamplerBindingType_NonFiltering => { @@ -1446,7 +1402,7 @@ pub fn map_bind_group_layout_entry( } else if is_storage_texture { wgt::BindingType::StorageTexture { access: map_storage_texture_access(entry.storageTexture.access) - .expect("invalid storage texture access for storage texture binding layout"), + .unwrap_or(wgt::StorageTextureAccess::WriteOnly), format: map_texture_format(entry.storageTexture.format) .expect("invalid texture format for storage texture binding layout"), view_dimension: match entry.storageTexture.viewDimension { @@ -1464,7 +1420,9 @@ pub fn map_bind_group_layout_entry( } else if is_buffer { wgt::BindingType::Buffer { ty: match entry.buffer.type_ { - native::WGPUBufferBindingType_Uniform => wgt::BufferBindingType::Uniform, + native::WGPUBufferBindingType_Uniform | native::WGPUBufferBindingType_Undefined => { + wgt::BufferBindingType::Uniform + } native::WGPUBufferBindingType_Storage => { wgt::BufferBindingType::Storage { read_only: false } } @@ -1490,7 +1448,7 @@ pub fn map_bind_group_layout_entry( wgt::BindGroupLayoutEntry { ty, binding: entry.binding, - visibility: wgt::ShaderStages::from_bits(entry.visibility) + visibility: from_u64_bits(entry.visibility) .expect("invalid visibility for bind group layout entry"), count: extras.and_then(|v| NonZeroU32::new(v.count)), } @@ -1504,12 +1462,12 @@ pub fn map_query_set_index(index: u32) -> Option { } #[inline] -pub fn map_query_set_descriptor<'a>( +pub unsafe fn map_query_set_descriptor<'a>( desc: &native::WGPUQuerySetDescriptor, extras: Option<&native::WGPUQuerySetDescriptorExtras>, ) -> wgt::QuerySetDescriptor> { wgt::QuerySetDescriptor { - label: ptr_into_label(desc.label), + label: string_view_into_label(desc.label), count: desc.count, ty: match (desc.type_, extras) { (native::WGPUQueryType_Occlusion, _) => wgt::QueryType::Occlusion, @@ -1596,12 +1554,12 @@ pub enum CreateSurfaceParams { pub unsafe fn map_surface( _: &native::WGPUSurfaceDescriptor, - win: Option<&native::WGPUSurfaceDescriptorFromWindowsHWND>, - xcb: Option<&native::WGPUSurfaceDescriptorFromXcbWindow>, - xlib: Option<&native::WGPUSurfaceDescriptorFromXlibWindow>, - wl: Option<&native::WGPUSurfaceDescriptorFromWaylandSurface>, - _metal: Option<&native::WGPUSurfaceDescriptorFromMetalLayer>, - android: Option<&native::WGPUSurfaceDescriptorFromAndroidNativeWindow>, + win: Option<&native::WGPUSurfaceSourceWindowsHWND>, + xcb: Option<&native::WGPUSurfaceSourceXCBWindow>, + xlib: Option<&native::WGPUSurfaceSourceXlibWindow>, + wl: Option<&native::WGPUSurfaceSourceWaylandSurface>, + _metal: Option<&native::WGPUSurfaceSourceMetalLayer>, + android: Option<&native::WGPUSurfaceSourceAndroidNativeWindow>, ) -> CreateSurfaceParams { if let Some(win) = win { let display_handle = raw_window_handle::WindowsDisplayHandle::new(); @@ -1680,7 +1638,7 @@ pub fn map_surface_configuration( .expect("invalid format for surface configuration"), width: config.width, height: config.height, - present_mode: map_present_mode(config.presentMode), + present_mode: map_present_mode(config.presentMode).unwrap_or(wgt::PresentMode::Fifo), alpha_mode: map_composite_alpha_mode(config.alphaMode) .expect("invalid alpha mode for surface configuration"), view_formats: make_slice(config.viewFormats, config.viewFormatCount) @@ -1715,3 +1673,11 @@ pub fn map_adapter_type(device_type: wgt::DeviceType) -> native::WGPUAdapterType wgt::DeviceType::Cpu => native::WGPUAdapterType_CPU, } } + +pub fn from_u64_bits>(value: u64) -> Option { + if value > u32::MAX.into() { + return None; + } + + T::from_bits(value as u32) +} diff --git a/src/lib.rs b/src/lib.rs index 3b585fc6..c132effd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,16 @@ use conv::{ - map_adapter_type, map_backend_type, map_bind_group_entry, map_bind_group_layout_entry, - map_device_descriptor, map_instance_backend_flags, map_instance_descriptor, - map_pipeline_layout_descriptor, map_primitive_state, map_query_set_descriptor, + from_u64_bits, map_adapter_type, map_backend_type, map_bind_group_entry, + map_bind_group_layout_entry, map_device_descriptor, map_instance_backend_flags, + map_instance_descriptor, map_pipeline_layout_descriptor, map_query_set_descriptor, map_query_set_index, map_shader_module, map_surface, map_surface_configuration, CreateSurfaceParams, }; +use core::slice; use parking_lot::Mutex; use smallvec::SmallVec; use std::{ borrow::Cow, error, - ffi::{CStr, CString}, fmt::Display, mem, num::NonZeroU64, @@ -18,11 +18,12 @@ use std::{ thread, }; use utils::{ - get_base_device_limits_from_adapter_limits, make_slice, ptr_into_label, ptr_into_path, + get_base_device_limits_from_adapter_limits, make_slice, str_into_string_view, + string_view_into_label, string_view_into_str, texture_format_has_depth, }; use wgc::{ - command::{bundle_ffi, DynComputePass, DynRenderPass}, - gfx_select, id, resource, Label, + command::{bundle_ffi, ComputePass, RenderPass}, + id, resource, Label, }; pub mod conv; @@ -48,7 +49,7 @@ impl Drop for WGPUAdapterImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.adapter_drop(self.id)); + context.adapter_drop(self.id); } } } @@ -61,7 +62,7 @@ impl Drop for WGPUBindGroupImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.bind_group_drop(self.id)); + context.bind_group_drop(self.id); } } } @@ -74,13 +75,13 @@ impl Drop for WGPUBindGroupLayoutImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.bind_group_layout_drop(self.id)); + context.bind_group_layout_drop(self.id); } } } struct BufferData { - usage: native::WGPUBufferUsageFlags, + usage: native::WGPUBufferUsage, size: u64, } pub struct WGPUBufferImpl { @@ -93,7 +94,7 @@ impl Drop for WGPUBufferImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.buffer_drop(self.id, false)); + context.buffer_drop(self.id); } } } @@ -107,7 +108,7 @@ impl Drop for WGPUCommandBufferImpl { fn drop(&mut self) { if self.open.load(atomic::Ordering::SeqCst) && !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.command_buffer_drop(self.id)); + context.command_buffer_drop(self.id); } } } @@ -122,14 +123,14 @@ impl Drop for WGPUCommandEncoderImpl { fn drop(&mut self) { if self.open.load(atomic::Ordering::SeqCst) && !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.command_encoder_drop(self.id)); + context.command_encoder_drop(self.id); } } } pub struct WGPUComputePassEncoderImpl { context: Arc, - encoder: *mut dyn DynComputePass, + encoder: *mut ComputePass, error_sink: ErrorSink, } impl Drop for WGPUComputePassEncoderImpl { @@ -152,7 +153,7 @@ impl Drop for WGPUComputePipelineImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.compute_pipeline_drop(self.id)); + context.compute_pipeline_drop(self.id); } } } @@ -165,7 +166,7 @@ impl Drop for QueueId { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.queue_drop(self.id)); + context.queue_drop(self.id); } } } @@ -181,12 +182,12 @@ impl Drop for WGPUDeviceImpl { if !thread::panicking() { let context = &self.context; - match gfx_select!(self.id => context.device_poll(self.id, wgt::Maintain::Wait)) { + match context.device_poll(self.id, wgt::Maintain::Wait) { Ok(_) => (), Err(err) => handle_error_fatal(err, "WGPUDeviceImpl::drop"), } - gfx_select!(self.id => context.device_drop(self.id)); + context.device_drop(self.id); } } } @@ -203,7 +204,7 @@ impl Drop for WGPUPipelineLayoutImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.pipeline_layout_drop(self.id)); + context.pipeline_layout_drop(self.id); } } } @@ -221,7 +222,7 @@ impl Drop for WGPUQuerySetImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.query_set_drop(self.id)); + context.query_set_drop(self.id); } } } @@ -239,7 +240,7 @@ impl Drop for WGPURenderBundleImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.render_bundle_drop(self.id)); + context.render_bundle_drop(self.id); } } } @@ -264,7 +265,7 @@ unsafe impl Sync for WGPURenderBundleEncoderImpl {} pub struct WGPURenderPassEncoderImpl { context: Arc, - encoder: *mut dyn DynRenderPass, + encoder: *mut RenderPass, error_sink: ErrorSink, } impl Drop for WGPURenderPassEncoderImpl { @@ -287,7 +288,7 @@ impl Drop for WGPURenderPipelineImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.render_pipeline_drop(self.id)); + context.render_pipeline_drop(self.id); } } } @@ -300,7 +301,7 @@ impl Drop for WGPUSamplerImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - gfx_select!(self.id => context.sampler_drop(self.id)); + context.sampler_drop(self.id); } } } @@ -314,14 +315,13 @@ impl Drop for WGPUShaderModuleImpl { if let Some(id) = self.id { if !thread::panicking() { let context = &self.context; - gfx_select!(id => context.shader_module_drop(id)); + context.shader_module_drop(id); } } } } struct SurfaceData { - device_id: id::DeviceId, error_sink: ErrorSink, texture_data: TextureData, } @@ -343,7 +343,7 @@ impl Drop for WGPUSurfaceImpl { #[derive(Copy, Clone)] struct TextureData { - usage: native::WGPUTextureUsageFlags, + usage: native::WGPUTextureUsage, dimension: native::WGPUTextureDimension, size: native::WGPUExtent3D, format: native::WGPUTextureFormat, @@ -369,7 +369,7 @@ impl Drop for WGPUTextureImpl { Some(surface_id) => { if !self.has_surface_presented.load(atomic::Ordering::SeqCst) { let context = &self.context; - match gfx_select!(self.id => context.surface_texture_discard(surface_id)) { + match context.surface_texture_discard(surface_id) { Ok(_) => (), Err(cause) => handle_error_fatal(cause, "wgpuTextureRelease"), } @@ -377,7 +377,7 @@ impl Drop for WGPUTextureImpl { } None => { let context = &self.context; - gfx_select!(self.id => context.texture_drop(self.id, false)); + context.texture_drop(self.id); } } } @@ -391,46 +391,56 @@ impl Drop for WGPUTextureViewImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - let _ = gfx_select!(self.id => context.texture_view_drop(self.id, false)); + let _ = context.texture_view_drop(self.id); } } } +const NULL_FUTURE: native::WGPUFuture = native::WGPUFuture { id: 0 }; +const EMPTY_STRING: native::WGPUStringView = native::WGPUStringView { + length: 0, + data: std::ptr::null(), +}; + struct DeviceCallback { callback: T, - userdata: *mut std::os::raw::c_void, + userdata: utils::Userdata, } unsafe impl Send for DeviceCallback {} -type UncapturedErrorCallback = DeviceCallback; +type UncapturedErrorCallback = DeviceCallback; type DeviceLostCallback = DeviceCallback; unsafe extern "C" fn default_uncaptured_error_handler( + _device: *const native::WGPUDevice, _typ: native::WGPUErrorType, - message: *const ::std::os::raw::c_char, - _userdata: *mut ::std::os::raw::c_void, + message: native::WGPUStringView, + _userdata1: *mut ::std::os::raw::c_void, + _userdata2: *mut ::std::os::raw::c_void, ) { - let message = unsafe { CStr::from_ptr(message) }.to_str().unwrap(); + let message = string_view_into_str(message).unwrap_or(""); log::warn!("Handling wgpu uncaptured errors as fatal by default"); panic!("wgpu uncaptured error:\n{message}\n"); } const DEFAULT_UNCAPTURED_ERROR_HANDLER: UncapturedErrorCallback = UncapturedErrorCallback { callback: Some(default_uncaptured_error_handler), - userdata: std::ptr::null_mut(), + userdata: utils::Userdata::NULL, }; unsafe extern "C" fn default_device_lost_handler( + _device: *const native::WGPUDevice, _reason: native::WGPUDeviceLostReason, - message: *const ::std::os::raw::c_char, - _userdata: *mut ::std::os::raw::c_void, + message: native::WGPUStringView, + _userdata1: *mut ::std::os::raw::c_void, + _userdata2: *mut ::std::os::raw::c_void, ) { - let message = unsafe { CStr::from_ptr(message) }.to_str().unwrap(); + let message = string_view_into_str(message).unwrap_or(""); log::warn!("Handling wgpu device lost errors as fatal by default"); panic!("wgpu device lost error:\n{message}\n"); } const DEFAULT_DEVICE_LOST_HANDLER: DeviceLostCallback = DeviceLostCallback { callback: Some(default_device_lost_handler), - userdata: std::ptr::null_mut(), + userdata: utils::Userdata::NULL, }; #[derive(Debug)] @@ -486,6 +496,7 @@ struct ErrorSinkRaw { scopes: Vec, uncaptured_handler: UncapturedErrorCallback, device_lost_handler: DeviceLostCallback, + device: Option, } impl ErrorSinkRaw { @@ -494,6 +505,7 @@ impl ErrorSinkRaw { scopes: Vec::new(), uncaptured_handler: DEFAULT_UNCAPTURED_ERROR_HANDLER, device_lost_handler, + device: None, } } @@ -502,13 +514,15 @@ impl ErrorSinkRaw { crate::Error::DeviceLost { .. } => { // handle device lost error early if let Some(callback) = self.device_lost_handler.callback { - let userdata = self.device_lost_handler.userdata; - let msg = CString::new(err.to_string()).unwrap(); + let userdata = &self.device_lost_handler.userdata; + let msg = err.to_string(); unsafe { callback( + &self.device.unwrap(), native::WGPUDeviceLostReason_Destroyed, - msg.as_ptr(), - userdata, + str_into_string_view(&msg), + userdata.get_1(), + userdata.get_2(), ); }; } @@ -537,9 +551,17 @@ impl ErrorSinkRaw { } None => { if let Some(callback) = self.uncaptured_handler.callback { - let userdata = self.uncaptured_handler.userdata; - let msg = CString::new(err.to_string()).unwrap(); - unsafe { callback(typ, msg.as_ptr(), userdata) }; + let userdata = &self.uncaptured_handler.userdata; + let msg = err.to_string(); + unsafe { + callback( + &self.device.unwrap(), + typ, + str_into_string_view(&msg), + userdata.get_1(), + userdata.get_2(), + ) + }; } } } @@ -626,10 +648,18 @@ pub unsafe extern "C" fn wgpuCreateInstance( descriptor: Option<&native::WGPUInstanceDescriptor>, ) -> native::WGPUInstance { let instance_desc = match descriptor { - Some(descriptor) => follow_chain!(map_instance_descriptor( - (descriptor), - WGPUSType_InstanceExtras => native::WGPUInstanceExtras - )), + Some(descriptor) => { + if descriptor.features.timedWaitAnyEnable != 0 + || descriptor.features.timedWaitAnyMaxCount > 0 + { + panic!("Unsupported timed WaitAny features specified"); + } + + follow_chain!(map_instance_descriptor( + (descriptor), + WGPUSType_InstanceExtras => native::WGPUInstanceExtras + )) + } None => wgt::InstanceDescriptor::default(), }; @@ -638,35 +668,50 @@ pub unsafe extern "C" fn wgpuCreateInstance( })) } +#[no_mangle] +pub unsafe extern "C" fn wgpuGetInstanceCapabilities( + capabilities: Option<&mut native::WGPUInstanceCapabilities>, +) -> native::WGPUStatus { + let capabilities = capabilities.expect("invalid return pointer \"capabilities\""); + // WaitAny is currently completely unsupported, so... + capabilities.timedWaitAnyEnable = false as native::WGPUBool; + capabilities.timedWaitAnyMaxCount = 0; + native::WGPUStatus_Success +} + // Adapter methods #[no_mangle] -pub unsafe extern "C" fn wgpuAdapterEnumerateFeatures( +pub unsafe extern "C" fn wgpuAdapterGetFeatures( adapter: native::WGPUAdapter, - features: *mut native::WGPUFeatureName, -) -> usize { + features: Option<&mut native::WGPUSupportedFeatures>, +) -> native::WGPUStatus { let (adapter_id, context) = { let adapter = adapter.as_ref().expect("invalid adapter"); (adapter.id, &adapter.context) }; - let adapter_features = match gfx_select!(adapter_id => context.adapter_features(adapter_id)) { - Ok(features) => features, - Err(err) => handle_error_fatal(err, "wgpuAdapterEnumerateFeatures"), - }; + let adapter_features = context.adapter_features(adapter_id); + let features = features.expect("invalid return pointer \"features\""); - let temp = conv::features_to_native(adapter_features); + return_features(features, adapter_features); - if !features.is_null() { - std::ptr::copy_nonoverlapping(temp.as_ptr(), features, temp.len()); - } + native::WGPUStatus_Success +} + +fn return_features(native: &mut native::WGPUSupportedFeatures, features: wgt::Features) { + let temp = conv::features_to_native(features); + let mut temp = temp.into_boxed_slice(); - temp.len() + native.featureCount = temp.len(); + native.features = temp.as_mut_ptr(); + + mem::forget(temp); } #[no_mangle] pub unsafe extern "C" fn wgpuAdapterGetLimits( adapter: native::WGPUAdapter, - limits: Option<&mut native::WGPUSupportedLimits>, + limits: Option<&mut native::WGPULimits>, ) -> native::WGPUBool { let (adapter_id, context) = { let adapter = adapter.as_ref().expect("invalid adapter"); @@ -674,11 +719,8 @@ pub unsafe extern "C" fn wgpuAdapterGetLimits( }; let limits = limits.expect("invalid return pointer \"limits\""); - let result = gfx_select!(adapter_id => context.adapter_limits(adapter_id)); - match result { - Ok(wgt_limits) => conv::write_limits_struct(wgt_limits, limits), - Err(err) => handle_error_fatal(err, "wgpuAdapterGetLimits"), - } + let wgt_limits = context.adapter_limits(adapter_id); + conv::write_limits_struct(wgt_limits, limits); true as native::WGPUBool // indicates that we can fill WGPUChainedStructOut } @@ -693,16 +735,12 @@ pub unsafe extern "C" fn wgpuAdapterGetInfo( let context = adapter.context.as_ref(); let adapter_id = adapter.id; - let result = gfx_select!(adapter_id => context.adapter_get_info(adapter_id)); - let result = match result { - Ok(info) => info, - Err(err) => handle_error_fatal(err, "wgpuAdapterGetInfo"), - }; + let result = context.adapter_get_info(adapter_id); - info.vendor = CString::new(result.driver).unwrap().into_raw(); - info.architecture = CString::default().into_raw(); // TODO(webgpu.h) - info.device = CString::new(result.name).unwrap().into_raw(); - info.description = CString::new(result.driver_info).unwrap().into_raw(); + info.vendor = utils::str_into_owned_string_view(&result.driver); + info.architecture = EMPTY_STRING; // TODO(webgpu.h) + info.device = utils::str_into_owned_string_view(&result.name); + info.description = utils::str_into_owned_string_view(&result.driver_info); info.backendType = map_backend_type(result.backend); info.adapterType = map_adapter_type(result.device_type); info.vendorID = result.vendor; @@ -718,10 +756,7 @@ pub unsafe extern "C" fn wgpuAdapterHasFeature( let adapter = adapter.as_ref().expect("invalid adapter"); (adapter.id, &adapter.context) }; - let adapter_features = match gfx_select!(adapter_id => context.adapter_features(adapter_id)) { - Ok(features) => features, - Err(err) => handle_error_fatal(err, "wgpuAdapterHasFeature"), - }; + let adapter_features = context.adapter_features(adapter_id); let feature = match conv::map_feature(feature) { Some(feature) => feature, @@ -733,46 +768,25 @@ pub unsafe extern "C" fn wgpuAdapterHasFeature( #[no_mangle] pub unsafe extern "C" fn wgpuAdapterInfoFreeMembers(adapter_info: native::WGPUAdapterInfo) { - drop(CString::from_raw( - adapter_info.vendor as *mut std::ffi::c_char, - )); - drop(CString::from_raw( - adapter_info.architecture as *mut std::ffi::c_char, - )); - drop(CString::from_raw( - adapter_info.device as *mut std::ffi::c_char, - )); - drop(CString::from_raw( - adapter_info.description as *mut std::ffi::c_char, - )); + utils::drop_string_view(adapter_info.vendor); + utils::drop_string_view(adapter_info.architecture); + utils::drop_string_view(adapter_info.device); + utils::drop_string_view(adapter_info.description); } #[no_mangle] pub unsafe extern "C" fn wgpuAdapterRequestDevice( adapter: native::WGPUAdapter, descriptor: Option<&native::WGPUDeviceDescriptor>, - callback: native::WGPUAdapterRequestDeviceCallback, - userdata: *mut std::os::raw::c_void, -) { + callback_info: native::WGPURequestDeviceCallbackInfo, +) -> native::WGPUFuture { let (adapter_id, context) = { let adapter = adapter.as_ref().expect("invalid adapter"); (adapter.id, &adapter.context) }; - let callback = callback.expect("invalid callback"); + let callback = callback_info.callback.expect("invalid callback"); - let adapter_limits = match gfx_select!(adapter_id => context.adapter_limits(adapter_id)) { - Ok(adapter_limits) => adapter_limits, - Err(cause) => { - let msg = CString::new(format_error(&cause)).unwrap(); - callback( - native::WGPURequestDeviceStatus_Error, - std::ptr::null(), - msg.as_ptr(), - userdata, - ); - return; - } - }; + let adapter_limits = context.adapter_limits(adapter_id); let base_limits = get_base_device_limits_from_adapter_limits(&adapter_limits); let (desc, trace_str, device_lost_handler, error_callback) = match descriptor { @@ -782,8 +796,8 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice( WGPUSType_DeviceExtras => native::WGPUDeviceExtras) ); let device_lost_handler = DeviceLostCallback { - callback: descriptor.deviceLostCallback, - userdata: descriptor.deviceLostUserdata, + callback: descriptor.deviceLostCallbackInfo.callback, + userdata: new_userdata!(descriptor.deviceLostCallbackInfo), }; (desc, trace_str, device_lost_handler, error_callback) } @@ -792,58 +806,63 @@ pub unsafe extern "C" fn wgpuAdapterRequestDevice( required_limits: base_limits, ..Default::default() }, - std::ptr::null(), + None, DEFAULT_DEVICE_LOST_HANDLER, None, ), }; - let (device_id, queue_id, err) = gfx_select!(adapter_id => - context.adapter_request_device( - adapter_id, - &desc, - ptr_into_path(trace_str), - None, - None - ) + let result = context.adapter_request_device( + adapter_id, + &desc, + trace_str.map(std::path::Path::new), + None, + None, ); - match err { - None => { - let message = CString::default(); + match result { + Ok((device_id, queue_id)) => { let mut error_sink = ErrorSinkRaw::new(device_lost_handler); if let Some(error_callback) = error_callback { error_sink.uncaptured_handler = error_callback; } + let error_sink = Arc::new(Mutex::new(error_sink)); + let device = Arc::into_raw(Arc::new(WGPUDeviceImpl { + context: context.clone(), + id: device_id, + queue: Arc::new(QueueId { + context: context.clone(), + id: queue_id, + }), + error_sink: error_sink.clone(), + })); + error_sink.lock().device = Some(device); + callback( native::WGPURequestDeviceStatus_Success, - Arc::into_raw(Arc::new(WGPUDeviceImpl { - context: context.clone(), - id: device_id, - queue: Arc::new(QueueId { - context: context.clone(), - id: queue_id, - }), - error_sink: Arc::new(Mutex::new(error_sink)), - })), - message.as_ptr(), - userdata, + device, + EMPTY_STRING, + callback_info.userdata1, + callback_info.userdata2, ); } - Some(err) => { - let message = CString::new(format_error(&err)).unwrap(); + Err(err) => { + let message = format_error(&err); callback( native::WGPURequestDeviceStatus_Error, std::ptr::null_mut(), - message.as_ptr(), - userdata, + str_into_string_view(&message), + callback_info.userdata1, + callback_info.userdata2, ); } - } + }; + + return NULL_FUTURE; } #[no_mangle] -pub unsafe extern "C" fn wgpuAdapterReference(adapter: native::WGPUAdapter) { +pub unsafe extern "C" fn wgpuAdapterAddRef(adapter: native::WGPUAdapter) { assert!(!adapter.is_null(), "invalid adapter"); Arc::increment_strong_count(adapter); } @@ -856,7 +875,7 @@ pub unsafe extern "C" fn wgpuAdapterRelease(adapter: native::WGPUAdapter) { // BindGroup methods #[no_mangle] -pub unsafe extern "C" fn wgpuBindGroupReference(bind_group: native::WGPUBindGroup) { +pub unsafe extern "C" fn wgpuBindGroupAddRef(bind_group: native::WGPUBindGroup) { assert!(!bind_group.is_null(), "invalid bind group"); Arc::increment_strong_count(bind_group); } @@ -869,9 +888,7 @@ pub unsafe extern "C" fn wgpuBindGroupRelease(bind_group: native::WGPUBindGroup) // BindGroupLayout methods #[no_mangle] -pub unsafe extern "C" fn wgpuBindGroupLayoutReference( - bind_group_layout: native::WGPUBindGroupLayout, -) { +pub unsafe extern "C" fn wgpuBindGroupLayoutAddRef(bind_group_layout: native::WGPUBindGroupLayout) { assert!(!bind_group_layout.is_null(), "invalid bind group layout"); Arc::increment_strong_count(bind_group_layout); } @@ -892,7 +909,7 @@ pub unsafe extern "C" fn wgpuBufferDestroy(buffer: native::WGPUBuffer) { (buffer.id, &buffer.context) }; // Per spec, no error to report. Even calling destroy multiple times is valid. - let _ = gfx_select!(buffer_id => context.buffer_destroy(buffer_id)); + let _ = context.buffer_destroy(buffer_id); } #[no_mangle] @@ -906,14 +923,14 @@ pub unsafe extern "C" fn wgpuBufferGetConstMappedRange( (buffer.id, &buffer.context) }; - let buf = match gfx_select!(buffer_id => context.buffer_get_mapped_range( + let buf = match context.buffer_get_mapped_range( buffer_id, offset as wgt::BufferAddress, match size { conv::WGPU_WHOLE_MAP_SIZE => None, _ => Some(size as u64), - } - )) { + }, + ) { Ok((ptr, _)) => ptr, Err(err) => handle_error_fatal(err, "wgpuBufferGetConstMappedRange"), }; @@ -932,14 +949,14 @@ pub unsafe extern "C" fn wgpuBufferGetMappedRange( (buffer.id, &buffer.context) }; - let buf = match gfx_select!(buffer_id => context.buffer_get_mapped_range( + let buf = match context.buffer_get_mapped_range( buffer_id, offset as wgt::BufferAddress, match size { conv::WGPU_WHOLE_MAP_SIZE => None, _ => Some(size as u64), - } - )) { + }, + ) { Ok((ptr, _)) => ptr, Err(err) => handle_error_fatal(err, "wgpuBufferGetMappedRange"), }; @@ -954,9 +971,7 @@ pub unsafe extern "C" fn wgpuBufferGetSize(buffer: native::WGPUBuffer) -> u64 { } #[no_mangle] -pub unsafe extern "C" fn wgpuBufferGetUsage( - buffer: native::WGPUBuffer, -) -> native::WGPUBufferUsageFlags { +pub unsafe extern "C" fn wgpuBufferGetUsage(buffer: native::WGPUBuffer) -> native::WGPUBufferUsage { let buffer = buffer.as_ref().expect("invalid buffer"); buffer.data.usage } @@ -964,18 +979,17 @@ pub unsafe extern "C" fn wgpuBufferGetUsage( #[no_mangle] pub unsafe extern "C" fn wgpuBufferMapAsync( buffer: native::WGPUBuffer, - mode: native::WGPUMapModeFlags, + mode: native::WGPUMapMode, offset: usize, size: usize, - callback: native::WGPUBufferMapAsyncCallback, - userdata: *mut std::ffi::c_void, -) { + callback_info: native::WGPUBufferMapCallbackInfo, +) -> native::WGPUFuture { let (buffer_id, context, error_sink) = { let buffer = buffer.as_ref().expect("invalid buffer"); (buffer.id, &buffer.context, &buffer.error_sink) }; - let callback = callback.expect("invalid callback"); - let userdata = utils::Userdata::new(userdata); + let callback = callback_info.callback.expect("invalid callback"); + let userdata = new_userdata!(callback_info); let operation = wgc::resource::BufferMapOperation { host: match mode as native::WGPUMapMode { @@ -985,36 +999,41 @@ pub unsafe extern "C" fn wgpuBufferMapAsync( }, callback: Some(wgc::resource::BufferMapCallback::from_rust(Box::new( move |result: resource::BufferAccessResult| { - let status = match result { - Ok(()) => native::WGPUBufferMapAsyncStatus_Success, - Err(resource::BufferAccessError::Device(_)) => { - native::WGPUBufferMapAsyncStatus_DeviceLost + let (status, message) = match result { + Ok(()) => (native::WGPUMapAsyncStatus_Success, String::default()), + Err(cause) => { + let code = match cause { + resource::BufferAccessError::MapAborted => { + native::WGPUMapAsyncStatus_Aborted + } + _ => native::WGPUMapAsyncStatus_Error, + }; + + (code, format_error(&cause)) } - Err(resource::BufferAccessError::MapAlreadyPending) => { - native::WGPUBufferMapAsyncStatus_MappingAlreadyPending - } - Err(resource::BufferAccessError::InvalidBufferId(_)) - | Err(resource::BufferAccessError::DestroyedResource(_)) => { - native::WGPUBufferMapAsyncStatus_DestroyedBeforeCallback - } - Err(_) => native::WGPUBufferMapAsyncStatus_ValidationError, - // TODO: WGPUBufferMapAsyncStatus_OffsetOutOfRange - // TODO: WGPUBufferMapAsyncStatus_SizeOutOfRange }; - callback(status, userdata.as_ptr()); + callback( + status, + str_into_string_view(&message), + userdata.get_1(), + userdata.get_2(), + ); }, ))), }; - if let Err(cause) = gfx_select!(buffer_id => context.buffer_map_async( + if let Err(cause) = context.buffer_map_async( buffer_id, offset as wgt::BufferAddress, Some(size as wgt::BufferAddress), operation, - )) { + ) { handle_error(error_sink, cause, None, "wgpuBufferMapAsync"); }; + + // TODO: Properly handle futures. + return NULL_FUTURE; } #[no_mangle] @@ -1024,13 +1043,13 @@ pub unsafe extern "C" fn wgpuBufferUnmap(buffer: native::WGPUBuffer) { (buffer.id, &buffer.context, &buffer.error_sink) }; - if let Err(cause) = gfx_select!(buffer_id => context.buffer_unmap(buffer_id)) { + if let Err(cause) = context.buffer_unmap(buffer_id) { handle_error(error_sink, cause, None, "wgpuBufferUnmap"); } } #[no_mangle] -pub unsafe extern "C" fn wgpuBufferReference(buffer: native::WGPUBuffer) { +pub unsafe extern "C" fn wgpuBufferAddRef(buffer: native::WGPUBuffer) { assert!(!buffer.is_null(), "invalid buffer"); Arc::increment_strong_count(buffer); } @@ -1043,7 +1062,7 @@ pub unsafe extern "C" fn wgpuBufferRelease(buffer: native::WGPUBuffer) { // CommandBuffer methods #[no_mangle] -pub unsafe extern "C" fn wgpuCommandBufferReference(command_buffer: native::WGPUCommandBuffer) { +pub unsafe extern "C" fn wgpuCommandBufferAddRef(command_buffer: native::WGPUCommandBuffer) { assert!(!command_buffer.is_null(), "invalid command buffer"); Arc::increment_strong_count(command_buffer); } @@ -1087,13 +1106,13 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginComputePass( let desc = match descriptor { Some(descriptor) => wgc::command::ComputePassDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), timestamp_writes: timestamp_writes.as_ref(), }, None => wgc::command::ComputePassDescriptor::default(), }; - let (pass, err) = gfx_select!(command_encoder_id => context.command_encoder_create_compute_pass_dyn(command_encoder_id, &desc)); + let (pass, err) = context.command_encoder_create_compute_pass(command_encoder_id, &desc); if let Some(cause) = err { handle_error( error_sink, @@ -1104,7 +1123,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginComputePass( } Arc::into_raw(Arc::new(WGPUComputePassEncoderImpl { context: context.clone(), - encoder: Box::into_raw(pass), + encoder: Box::into_raw(Box::new(pass)), error_sink: error_sink.clone(), })) } @@ -1164,7 +1183,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginRenderPass( }); let desc = wgc::command::RenderPassDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), color_attachments: Cow::Owned( make_slice(descriptor.colorAttachments, descriptor.colorAttachmentCount) .iter() @@ -1195,7 +1214,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginRenderPass( occlusion_query_set: descriptor.occlusionQuerySet.as_ref().map(|v| v.id), }; - let (pass, err) = gfx_select!(command_encoder_id => context.command_encoder_create_render_pass_dyn(command_encoder_id, &desc)); + let (pass, err) = context.command_encoder_create_render_pass(command_encoder_id, &desc); if let Some(cause) = err { handle_error( error_sink, @@ -1206,7 +1225,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginRenderPass( } Arc::into_raw(Arc::new(WGPURenderPassEncoderImpl { context: context.clone(), - encoder: Box::into_raw(pass), + encoder: Box::into_raw(Box::new(pass)), error_sink: error_sink.clone(), })) } @@ -1228,7 +1247,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderClearBuffer( }; let buffer_id = buffer.as_ref().expect("invalid buffer").id; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_clear_buffer( + if let Err(cause) = context.command_encoder_clear_buffer( command_encoder_id, buffer_id, offset, @@ -1236,8 +1255,8 @@ pub unsafe extern "C" fn wgpuCommandEncoderClearBuffer( 0 => panic!("invalid size"), conv::WGPU_WHOLE_SIZE => None, _ => Some(size), - } - )) { + }, + ) { handle_error(error_sink, cause, None, "wgpuCommandEncoderClearBuffer"); } } @@ -1262,14 +1281,14 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyBufferToBuffer( let source_buffer_id = source.as_ref().expect("invalid source").id; let destination_buffer_id = destination.as_ref().expect("invalid destination").id; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_copy_buffer_to_buffer( + if let Err(cause) = context.command_encoder_copy_buffer_to_buffer( command_encoder_id, source_buffer_id, source_offset, destination_buffer_id, destination_offset, - size - )) { + size, + ) { handle_error( error_sink, cause, @@ -1282,8 +1301,8 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyBufferToBuffer( #[no_mangle] pub unsafe extern "C" fn wgpuCommandEncoderCopyBufferToTexture( command_encoder: native::WGPUCommandEncoder, - source: Option<&native::WGPUImageCopyBuffer>, - destination: Option<&native::WGPUImageCopyTexture>, + source: Option<&native::WGPUTexelCopyBufferInfo>, + destination: Option<&native::WGPUTexelCopyTextureInfo>, copy_size: Option<&native::WGPUExtent3D>, ) { let (command_encoder_id, context, error_sink) = { @@ -1295,12 +1314,12 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyBufferToTexture( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_copy_buffer_to_texture( + if let Err(cause) = context.command_encoder_copy_buffer_to_texture( command_encoder_id, &conv::map_image_copy_buffer(source.expect("invalid source")), &conv::map_image_copy_texture(destination.expect("invalid destination")), - &conv::map_extent3d(copy_size.expect("invalid copy size")) - )) { + &conv::map_extent3d(copy_size.expect("invalid copy size")), + ) { handle_error( error_sink, cause, @@ -1313,8 +1332,8 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyBufferToTexture( #[no_mangle] pub unsafe extern "C" fn wgpuCommandEncoderCopyTextureToBuffer( command_encoder: native::WGPUCommandEncoder, - source: Option<&native::WGPUImageCopyTexture>, - destination: Option<&native::WGPUImageCopyBuffer>, + source: Option<&native::WGPUTexelCopyTextureInfo>, + destination: Option<&native::WGPUTexelCopyBufferInfo>, copy_size: Option<&native::WGPUExtent3D>, ) { let (command_encoder_id, context, error_sink) = { @@ -1326,12 +1345,12 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyTextureToBuffer( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_copy_texture_to_buffer( + if let Err(cause) = context.command_encoder_copy_texture_to_buffer( command_encoder_id, &conv::map_image_copy_texture(source.expect("invalid source")), &conv::map_image_copy_buffer(destination.expect("invalid destination")), - &conv::map_extent3d(copy_size.expect("invalid copy size")) - )) { + &conv::map_extent3d(copy_size.expect("invalid copy size")), + ) { handle_error( error_sink, cause, @@ -1344,8 +1363,8 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyTextureToBuffer( #[no_mangle] pub unsafe extern "C" fn wgpuCommandEncoderCopyTextureToTexture( command_encoder: native::WGPUCommandEncoder, - source: Option<&native::WGPUImageCopyTexture>, - destination: Option<&native::WGPUImageCopyTexture>, + source: Option<&native::WGPUTexelCopyTextureInfo>, + destination: Option<&native::WGPUTexelCopyTextureInfo>, copy_size: Option<&native::WGPUExtent3D>, ) { let (command_encoder_id, context, error_sink) = { @@ -1357,12 +1376,12 @@ pub unsafe extern "C" fn wgpuCommandEncoderCopyTextureToTexture( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_copy_texture_to_texture( + if let Err(cause) = context.command_encoder_copy_texture_to_texture( command_encoder_id, &conv::map_image_copy_texture(source.expect("invalid source")), &conv::map_image_copy_texture(destination.expect("invalid destination")), - &conv::map_extent3d(copy_size.expect("invalid copy size")) - )) { + &conv::map_extent3d(copy_size.expect("invalid copy size")), + ) { handle_error( error_sink, cause, @@ -1387,12 +1406,12 @@ pub unsafe extern "C" fn wgpuCommandEncoderFinish( let desc = match descriptor { Some(descriptor) => wgt::CommandBufferDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), }, None => wgt::CommandBufferDescriptor::default(), }; - let (command_buffer_id, error) = gfx_select!(command_encoder_id => context.command_encoder_finish(command_encoder_id, &desc)); + let (command_buffer_id, error) = context.command_encoder_finish(command_encoder_id, &desc); if let Some(cause) = error { handle_error(error_sink, cause, None, "wgpuCommandEncoderFinish"); } @@ -1407,7 +1426,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderFinish( #[no_mangle] pub unsafe extern "C" fn wgpuCommandEncoderInsertDebugMarker( command_encoder: native::WGPUCommandEncoder, - marker_label: *const std::ffi::c_char, + marker_label: native::WGPUStringView, ) { let (command_encoder_id, context, error_sink) = { let command_encoder = command_encoder.as_ref().expect("invalid command encoder"); @@ -1418,8 +1437,10 @@ pub unsafe extern "C" fn wgpuCommandEncoderInsertDebugMarker( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_insert_debug_marker(command_encoder_id, CStr::from_ptr(marker_label).to_str().unwrap())) - { + if let Err(cause) = context.command_encoder_insert_debug_marker( + command_encoder_id, + string_view_into_str(marker_label).unwrap_or(""), + ) { handle_error( error_sink, cause, @@ -1442,8 +1463,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderPopDebugGroup( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_pop_debug_group(command_encoder_id)) - { + if let Err(cause) = context.command_encoder_pop_debug_group(command_encoder_id) { handle_error(error_sink, cause, None, "wgpuCommandEncoderPopDebugGroup"); } } @@ -1451,7 +1471,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderPopDebugGroup( #[no_mangle] pub unsafe extern "C" fn wgpuCommandEncoderPushDebugGroup( command_encoder: native::WGPUCommandEncoder, - group_label: *const std::ffi::c_char, + group_label: native::WGPUStringView, ) { let (command_encoder_id, context, error_sink) = { let command_encoder = command_encoder.as_ref().expect("invalid command encoder"); @@ -1462,8 +1482,10 @@ pub unsafe extern "C" fn wgpuCommandEncoderPushDebugGroup( ) }; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_push_debug_group(command_encoder_id, CStr::from_ptr(group_label).to_str().unwrap())) - { + if let Err(cause) = context.command_encoder_push_debug_group( + command_encoder_id, + string_view_into_str(group_label).unwrap_or(""), + ) { handle_error(error_sink, cause, None, "wgpuCommandEncoderPushDebugGroup"); } } @@ -1488,14 +1510,14 @@ pub unsafe extern "C" fn wgpuCommandEncoderResolveQuerySet( let query_set_id = query_set.as_ref().expect("invalid query set").id; let destination_buffer_id = destination.as_ref().expect("invalid destination").id; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_resolve_query_set( + if let Err(cause) = context.command_encoder_resolve_query_set( command_encoder_id, query_set_id, first_query, query_count, destination_buffer_id, - destination_offset - )) { + destination_offset, + ) { handle_error(error_sink, cause, None, "wgpuCommandEncoderResolveQuerySet"); } } @@ -1516,17 +1538,15 @@ pub unsafe extern "C" fn wgpuCommandEncoderWriteTimestamp( }; let query_set_id = query_set.as_ref().expect("invalid query set").id; - if let Err(cause) = gfx_select!(command_encoder_id => context.command_encoder_write_timestamp( - command_encoder_id, - query_set_id, - query_index - )) { + if let Err(cause) = + context.command_encoder_write_timestamp(command_encoder_id, query_set_id, query_index) + { handle_error(error_sink, cause, None, "wgpuCommandEncoderWriteTimestamp"); } } #[no_mangle] -pub unsafe extern "C" fn wgpuCommandEncoderReference(command_encoder: native::WGPUCommandEncoder) { +pub unsafe extern "C" fn wgpuCommandEncoderAddRef(command_encoder: native::WGPUCommandEncoder) { assert!(!command_encoder.is_null(), "invalid command encoder"); Arc::increment_strong_count(command_encoder); } @@ -1546,10 +1566,10 @@ pub unsafe extern "C" fn wgpuComputePassEncoderDispatchWorkgroups( workgroup_count_z: u32, ) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.dispatch_workgroups( - &pass.context, + match pass.context.compute_pass_dispatch_workgroups( + encoder, workgroup_count_x, workgroup_count_y, workgroup_count_z, @@ -1576,9 +1596,13 @@ pub unsafe extern "C" fn wgpuComputePassEncoderDispatchWorkgroupsIndirect( .expect("invalid indirect buffer") .id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.dispatch_workgroups_indirect(&pass.context, indirect_buffer_id, indirect_offset) { + match pass.context.compute_pass_dispatch_workgroups_indirect( + encoder, + indirect_buffer_id, + indirect_offset, + ) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -1592,9 +1616,9 @@ pub unsafe extern "C" fn wgpuComputePassEncoderDispatchWorkgroupsIndirect( #[no_mangle] pub unsafe extern "C" fn wgpuComputePassEncoderEnd(pass: native::WGPUComputePassEncoder) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.end(&pass.context) { + match pass.context.compute_pass_end(encoder) { Ok(()) => (), Err(cause) => handle_error(&pass.error_sink, cause, None, "wgpuComputePassEncoderEnd"), } @@ -1603,14 +1627,14 @@ pub unsafe extern "C" fn wgpuComputePassEncoderEnd(pass: native::WGPUComputePass #[no_mangle] pub unsafe extern "C" fn wgpuComputePassEncoderInsertDebugMarker( pass: native::WGPUComputePassEncoder, - marker_label: *const std::ffi::c_char, + marker_label: native::WGPUStringView, ) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.insert_debug_marker( - &pass.context, - CStr::from_ptr(marker_label).to_str().unwrap(), + match pass.context.compute_pass_insert_debug_marker( + encoder, + string_view_into_str(marker_label).unwrap_or(""), 0, ) { Ok(()) => (), @@ -1626,9 +1650,9 @@ pub unsafe extern "C" fn wgpuComputePassEncoderInsertDebugMarker( #[no_mangle] pub unsafe extern "C" fn wgpuComputePassEncoderPopDebugGroup(pass: native::WGPUComputePassEncoder) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.pop_debug_group(&pass.context) { + match pass.context.compute_pass_pop_debug_group(encoder) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -1642,14 +1666,14 @@ pub unsafe extern "C" fn wgpuComputePassEncoderPopDebugGroup(pass: native::WGPUC #[no_mangle] pub unsafe extern "C" fn wgpuComputePassEncoderPushDebugGroup( pass: native::WGPUComputePassEncoder, - group_label: *const std::ffi::c_char, + group_label: native::WGPUStringView, ) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.push_debug_group( - &pass.context, - CStr::from_ptr(group_label).to_str().unwrap(), + match pass.context.compute_pass_push_debug_group( + encoder, + string_view_into_str(group_label).unwrap_or(""), 0, ) { Ok(()) => (), @@ -1673,12 +1697,12 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetBindGroup( let pass = pass.as_ref().expect("invalid compute pass"); //TODO: as per webgpu.h bindgroup is nullable let bind_group_id = bind_group.as_ref().expect("invalid bind group").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_bind_group( - &pass.context, + match pass.context.compute_pass_set_bind_group( + encoder, group_index, - bind_group_id, + Some(bind_group_id), make_slice(dynamic_offsets, dynamic_offset_count), ) { Ok(()) => (), @@ -1701,9 +1725,12 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetPipeline( .as_ref() .expect("invalid compute pipeline") .id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_pipeline(&pass.context, compute_pipeline_id) { + match pass + .context + .compute_pass_set_pipeline(encoder, compute_pipeline_id) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -1715,7 +1742,7 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetPipeline( } #[no_mangle] -pub unsafe extern "C" fn wgpuComputePassEncoderReference( +pub unsafe extern "C" fn wgpuComputePassEncoderAddRef( compute_pass_encoder: native::WGPUComputePassEncoder, ) { assert!( @@ -1747,7 +1774,8 @@ pub unsafe extern "C" fn wgpuComputePipelineGetBindGroupLayout( (pipeline.id, &pipeline.context, &pipeline.error_sink) }; - let (bind_group_layout_id, error) = gfx_select!(pipeline_id => context.compute_pipeline_get_bind_group_layout(pipeline_id, group_index, None)); + let (bind_group_layout_id, error) = + context.compute_pipeline_get_bind_group_layout(pipeline_id, group_index, None); if let Some(cause) = error { handle_error( error_sink, @@ -1764,9 +1792,7 @@ pub unsafe extern "C" fn wgpuComputePipelineGetBindGroupLayout( } #[no_mangle] -pub unsafe extern "C" fn wgpuComputePipelineReference( - compute_pipeline: native::WGPUComputePipeline, -) { +pub unsafe extern "C" fn wgpuComputePipelineAddRef(compute_pipeline: native::WGPUComputePipeline) { assert!(!compute_pipeline.is_null(), "invalid command pipeline"); Arc::increment_strong_count(compute_pipeline); } @@ -1804,12 +1830,11 @@ pub unsafe extern "C" fn wgpuDeviceCreateBindGroup( .collect::>(); let desc = wgc::binding_model::BindGroupDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), layout: bind_group_layout_id, entries: Cow::Borrowed(&entries), }; - let (bind_group_id, error) = - gfx_select!(device_id => context.device_create_bind_group(device_id, &desc, None)); + let (bind_group_id, error) = context.device_create_bind_group(device_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, desc.label, "wgpuDeviceCreateBindGroup"); } @@ -1841,11 +1866,11 @@ pub unsafe extern "C" fn wgpuDeviceCreateBindGroupLayout( .collect::>(); let desc = wgc::binding_model::BindGroupLayoutDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), entries: Cow::Borrowed(&entries), }; let (bind_group_layout_id, error) = - gfx_select!(device_id => context.device_create_bind_group_layout(device_id, &desc, None)); + context.device_create_bind_group_layout(device_id, &desc, None); if let Some(cause) = error { handle_error( error_sink, @@ -1873,14 +1898,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateBuffer( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgt::BufferDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), size: descriptor.size, - usage: wgt::BufferUsages::from_bits(descriptor.usage).expect("invalid buffer usage"), + usage: from_u64_bits(descriptor.usage).expect("invalid buffer usage"), mapped_at_creation: descriptor.mappedAtCreation != 0, }; - let (buffer_id, error) = - gfx_select!(device_id => context.device_create_buffer(device_id, &desc, None)); + let (buffer_id, error) = context.device_create_buffer(device_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, desc.label, "wgpuDeviceCreateBuffer"); } @@ -1907,12 +1931,11 @@ pub unsafe extern "C" fn wgpuDeviceCreateCommandEncoder( }; let desc = match descriptor { Some(descriptor) => wgt::CommandEncoderDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), }, None => wgt::CommandEncoderDescriptor::default(), }; - let (command_encoder_id, error) = - gfx_select!(device_id => context.device_create_command_encoder(device_id, &desc, None)); + let (command_encoder_id, error) = context.device_create_command_encoder(device_id, &desc, None); if let Some(cause) = error { handle_error( error_sink, @@ -1942,7 +1965,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateComputePipeline( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgc::pipeline::ComputePipelineDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), layout: descriptor.layout.as_ref().map(|v| v.id), stage: wgc::pipeline::ProgrammableStageDescriptor { module: descriptor @@ -1952,7 +1975,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateComputePipeline( .expect("invalid fragment shader module for render pipeline descriptor") .id .expect("invalid fragment shader module for render pipeline descriptor"), - entry_point: ptr_into_label(descriptor.compute.entryPoint), + entry_point: string_view_into_label(descriptor.compute.entryPoint), constants: Cow::Owned( make_slice( descriptor.compute.constants, @@ -1961,7 +1984,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateComputePipeline( .iter() .map(|entry| { ( - CStr::from_ptr(entry.key).to_str().unwrap().to_string(), + string_view_into_str(entry.key).unwrap_or("").to_string(), entry.value, ) }) @@ -1969,19 +1992,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateComputePipeline( ), // TODO(wgpu.h) zero_initialize_workgroup_memory: false, - // TODO(wgpu.h) - vertex_pulling_transform: false, }, // TODO(wgpu.h) cache: None, }; - let (compute_pipeline_id, error) = gfx_select!(device_id => context.device_create_compute_pipeline( - device_id, - &desc, - None, - None - )); + let (compute_pipeline_id, error) = + context.device_create_compute_pipeline(device_id, &desc, None, None); if let Some(cause) = error { if let wgc::pipeline::CreateComputePipelineError::Internal(ref error) = cause { log::warn!( @@ -2022,8 +2039,7 @@ pub unsafe extern "C" fn wgpuDeviceCreatePipelineLayout( (descriptor), WGPUSType_PipelineLayoutExtras => native::WGPUPipelineLayoutExtras) ); - let (pipeline_layout_id, error) = - gfx_select!(device_id => context.device_create_pipeline_layout(device_id, &desc, None)); + let (pipeline_layout_id, error) = context.device_create_pipeline_layout(device_id, &desc, None); if let Some(cause) = error { handle_error( error_sink, @@ -2056,8 +2072,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateQuerySet( WGPUSType_QuerySetDescriptorExtras => native::WGPUQuerySetDescriptorExtras) ); - let (query_set_id, error) = - gfx_select!(device_id => context.device_create_query_set(device_id, &desc, None)); + let (query_set_id, error) = context.device_create_query_set(device_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, desc.label, "wgpuDeviceCreateQuerySet"); } @@ -2084,7 +2099,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderBundleEncoder( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgc::command::RenderBundleEncoderDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), color_formats: make_slice(descriptor.colorFormats, descriptor.colorFormatCount) .iter() .map(|format| conv::map_texture_format(*format)) @@ -2123,7 +2138,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgc::pipeline::RenderPipelineDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), layout: descriptor.layout.as_ref().map(|v| v.id), vertex: wgc::pipeline::VertexState { stage: wgc::pipeline::ProgrammableStageDescriptor { @@ -2134,13 +2149,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( .expect("invalid vertex shader module for vertex state") .id .expect("invalid vertex shader module for vertex state"), - entry_point: ptr_into_label(descriptor.vertex.entryPoint), + entry_point: string_view_into_label(descriptor.vertex.entryPoint), constants: Cow::Owned( make_slice(descriptor.vertex.constants, descriptor.vertex.constantCount) .iter() .map(|entry| { ( - CStr::from_ptr(entry.key).to_str().unwrap().to_string(), + string_view_into_str(entry.key).unwrap_or("").to_string(), entry.value, ) }) @@ -2148,8 +2163,6 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( ), // TODO(wgpu.h) zero_initialize_workgroup_memory: false, - // TODO(wgpu.h) - vertex_pulling_transform: false, }, buffers: Cow::Owned( make_slice(descriptor.vertex.buffers, descriptor.vertex.bufferCount) @@ -2177,37 +2190,46 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( ), }, primitive: wgt::PrimitiveState { - topology: conv::map_primitive_topology(descriptor.primitive.topology), + topology: conv::map_primitive_topology(descriptor.primitive.topology) + .unwrap_or(wgt::PrimitiveTopology::TriangleList), strip_index_format: conv::map_index_format(descriptor.primitive.stripIndexFormat).ok(), front_face: match descriptor.primitive.frontFace { - native::WGPUFrontFace_CCW => wgt::FrontFace::Ccw, + native::WGPUFrontFace_CCW | native::WGPUFrontFace_Undefined => wgt::FrontFace::Ccw, native::WGPUFrontFace_CW => wgt::FrontFace::Cw, _ => panic!("invalid front face for primitive state"), }, cull_mode: match descriptor.primitive.cullMode { - native::WGPUCullMode_None => None, + native::WGPUCullMode_None | native::WGPUCullMode_Undefined => None, native::WGPUCullMode_Front => Some(wgt::Face::Front), native::WGPUCullMode_Back => Some(wgt::Face::Back), _ => panic!("invalid cull mode for primitive state"), }, - unclipped_depth: follow_chain!( - map_primitive_state( - (&descriptor.primitive), - WGPUSType_PrimitiveDepthClipControl => native::WGPUPrimitiveDepthClipControl - ) - ), + unclipped_depth: descriptor.primitive.unclippedDepth != 0, polygon_mode: wgt::PolygonMode::Fill, conservative: false, }, - depth_stencil: descriptor - .depthStencil - .as_ref() - .map(|desc| wgt::DepthStencilState { - format: conv::map_texture_format(desc.format) - .expect("invalid texture format for depth stencil state"), - depth_write_enabled: desc.depthWriteEnabled != 0, + depth_stencil: descriptor.depthStencil.as_ref().map(|desc| { + let format = conv::map_texture_format(desc.format) + .expect("invalid texture format for depth stencil state"); + + // Validation per spec. + if texture_format_has_depth(format) { + if desc.depthWriteEnabled == native::WGPUOptionalBool_Undefined { + panic!("Depth write not specified for depth format") + } + } else { + if desc.depthWriteEnabled == native::WGPUOptionalBool_True { + panic!("Depth write enabled for non-depth format") + } + } + + wgt::DepthStencilState { + format, + depth_write_enabled: desc.depthWriteEnabled == native::WGPUOptionalBool_True, + // TODO: Is validation correct if we return always for undefined depth compare? depth_compare: conv::map_compare_function(desc.depthCompare) - .expect("invalid depth compare function for depth stencil state"), + .expect("invalid depth compare function for depth stencil state") + .unwrap_or(wgt::CompareFunction::Always), stencil: wgt::StencilState { front: conv::map_stencil_face_state(desc.stencilFront, "front"), back: conv::map_stencil_face_state(desc.stencilBack, "back"), @@ -2219,7 +2241,8 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( slope_scale: desc.depthBiasSlopeScale, clamp: desc.depthBiasClamp, }, - }), + } + }), multisample: wgt::MultisampleState { count: descriptor.multisample.count, mask: descriptor.multisample.mask as u64, @@ -2236,13 +2259,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( .expect("invalid fragment shader module for render pipeline descriptor") .id .expect("invalid fragment shader module for render pipeline descriptor"), - entry_point: ptr_into_label(fragment.entryPoint), + entry_point: string_view_into_label(fragment.entryPoint), constants: Cow::Owned( make_slice(fragment.constants, fragment.constantCount) .iter() .map(|entry| { ( - CStr::from_ptr(entry.key).to_str().unwrap().to_string(), + string_view_into_str(entry.key).unwrap_or("").to_string(), entry.value, ) }) @@ -2250,8 +2273,6 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( ), // TODO(wgpu.h) zero_initialize_workgroup_memory: false, - // TODO(wgpu.h) - vertex_pulling_transform: false, }, targets: Cow::Owned( make_slice(fragment.targets, fragment.targetCount) @@ -2266,8 +2287,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( alpha: conv::map_blend_component(blend.alpha), } }), - write_mask: wgt::ColorWrites::from_bits(color_target.writeMask) - .unwrap(), + write_mask: from_u64_bits(color_target.writeMask).unwrap(), } }) }) @@ -2280,7 +2300,8 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( cache: None, }; - let (render_pipeline_id, error) = gfx_select!(device_id => context.device_create_render_pipeline(device_id, &desc, None, None)); + let (render_pipeline_id, error) = + context.device_create_render_pipeline(device_id, &desc, None, None); if let Some(cause) = error { if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause { log::error!("Shader translation error for stage {:?}: {}", stage, error); @@ -2313,18 +2334,25 @@ pub unsafe extern "C" fn wgpuDeviceCreateSampler( let desc = match descriptor { Some(descriptor) => wgc::resource::SamplerDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), address_modes: [ - conv::map_address_mode(descriptor.addressModeU), - conv::map_address_mode(descriptor.addressModeV), - conv::map_address_mode(descriptor.addressModeW), + conv::map_address_mode(descriptor.addressModeU) + .unwrap_or(wgt::AddressMode::ClampToEdge), + conv::map_address_mode(descriptor.addressModeV) + .unwrap_or(wgt::AddressMode::ClampToEdge), + conv::map_address_mode(descriptor.addressModeW) + .unwrap_or(wgt::AddressMode::ClampToEdge), ], - mag_filter: conv::map_filter_mode(descriptor.magFilter), - min_filter: conv::map_filter_mode(descriptor.minFilter), - mipmap_filter: conv::map_mipmap_filter_mode(descriptor.mipmapFilter), + mag_filter: conv::map_filter_mode(descriptor.magFilter) + .unwrap_or(wgt::FilterMode::Nearest), + min_filter: conv::map_filter_mode(descriptor.minFilter) + .unwrap_or(wgt::FilterMode::Nearest), + mipmap_filter: conv::map_mipmap_filter_mode(descriptor.mipmapFilter) + .unwrap_or(wgt::FilterMode::Nearest), lod_min_clamp: descriptor.lodMinClamp, lod_max_clamp: descriptor.lodMaxClamp, - compare: conv::map_compare_function(descriptor.compare).ok(), + compare: conv::map_compare_function(descriptor.compare) + .expect("Invalid compare function"), anisotropy_clamp: descriptor.maxAnisotropy, // TODO(wgpu.h) border_color: None, @@ -2350,8 +2378,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateSampler( }, }; - let (sampler_id, error) = - gfx_select!(device_id => context.device_create_sampler(device_id, &desc, None)); + let (sampler_id, error) = context.device_create_sampler(device_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, desc.label, "wgpuDeviceCreateSampler"); } @@ -2374,14 +2401,14 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgc::pipeline::ShaderModuleDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), shader_bound_checks: wgt::ShaderBoundChecks::default(), }; let source = match follow_chain!( map_shader_module((descriptor), - WGPUSType_ShaderModuleSPIRVDescriptor => native::WGPUShaderModuleSPIRVDescriptor, - WGPUSType_ShaderModuleWGSLDescriptor => native::WGPUShaderModuleWGSLDescriptor, + WGPUSType_ShaderSourceSPIRV => native::WGPUShaderSourceSPIRV, + WGPUSType_ShaderSourceWGSL => native::WGPUShaderSourceWGSL, WGPUSType_ShaderModuleGLSLDescriptor => native::WGPUShaderModuleGLSLDescriptor) ) { Ok(source) => source, @@ -2400,7 +2427,8 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModule( } }; - let (shader_module_id, error) = gfx_select!(device_id => context.device_create_shader_module(device_id, &desc, source, None)); + let (shader_module_id, error) = + context.device_create_shader_module(device_id, &desc, source, None); if let Some(cause) = error { handle_error( error_sink, @@ -2428,14 +2456,15 @@ pub unsafe extern "C" fn wgpuDeviceCreateTexture( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgt::TextureDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), size: conv::map_extent3d(&descriptor.size), mip_level_count: descriptor.mipLevelCount, sample_count: descriptor.sampleCount, - dimension: conv::map_texture_dimension(descriptor.dimension), + dimension: conv::map_texture_dimension(descriptor.dimension) + .unwrap_or(wgt::TextureDimension::D2), format: conv::map_texture_format(descriptor.format) .expect("invalid texture format for texture descriptor"), - usage: wgt::TextureUsages::from_bits(descriptor.usage) + usage: from_u64_bits(descriptor.usage) .expect("invalid texture usage for texture descriptor"), view_formats: make_slice(descriptor.viewFormats, descriptor.viewFormatCount) .iter() @@ -2445,8 +2474,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateTexture( .collect(), }; - let (texture_id, error) = - gfx_select!(device_id => context.device_create_texture(device_id, &desc, None)); + let (texture_id, error) = context.device_create_texture(device_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, desc.label, "wgpuDeviceCreateTexture"); } @@ -2474,32 +2502,38 @@ pub extern "C" fn wgpuDeviceDestroy(_device: native::WGPUDevice) { } #[no_mangle] -pub unsafe extern "C" fn wgpuDeviceEnumerateFeatures( +pub unsafe extern "C" fn wgpuDeviceGetFeatures( device: native::WGPUDevice, - features: *mut native::WGPUFeatureName, -) -> usize { + features: Option<&mut native::WGPUSupportedFeatures>, +) -> native::WGPUStatus { let (device_id, context) = { let device = device.as_ref().expect("invalid device"); (device.id, &device.context) }; - let device_features = match gfx_select!(device_id => context.device_features(device_id)) { - Ok(features) => features, - Err(err) => handle_error_fatal(err, "wgpuDeviceEnumerateFeatures"), - }; + let device_features = context.device_features(device_id); + let features = features.expect("invalid return pointer \"features\""); - let temp = conv::features_to_native(device_features); + return_features(features, device_features); - if !features.is_null() { - std::ptr::copy_nonoverlapping(temp.as_ptr(), features, temp.len()); - } + native::WGPUStatus_Success +} - temp.len() +#[no_mangle] +pub unsafe extern "C" fn wgpuSupportedFeaturesFreeMembers( + supported_features: native::WGPUSupportedFeatures, +) { + if !supported_features.features.is_null() && supported_features.featureCount > 0 { + drop(Box::from_raw(slice::from_raw_parts_mut( + supported_features.features as *mut native::WGPUFeatureName, + supported_features.featureCount, + ))) + } } #[no_mangle] pub unsafe extern "C" fn wgpuDeviceGetLimits( device: native::WGPUDevice, - limits: Option<&mut native::WGPUSupportedLimits>, + limits: Option<&mut native::WGPULimits>, ) -> native::WGPUBool { let (device_id, context) = { let device = device.as_ref().expect("invalid device"); @@ -2507,11 +2541,8 @@ pub unsafe extern "C" fn wgpuDeviceGetLimits( }; let limits = limits.expect("invalid return pointer \"limits\""); - let result = gfx_select!(device_id => context.device_limits(device_id)); - match result { - Ok(wgt_limits) => conv::write_limits_struct(wgt_limits, limits), - Err(err) => handle_error_fatal(err, "wgpuDeviceGetLimits"), - } + let wgt_limits = context.device_limits(device_id); + conv::write_limits_struct(wgt_limits, limits); true as native::WGPUBool // indicates that we can fill WGPUChainedStructOut } @@ -2538,10 +2569,7 @@ pub unsafe extern "C" fn wgpuDeviceHasFeature( let device = device.as_ref().expect("invalid device"); (device.id, &device.context) }; - let device_features = match gfx_select!(device_id => context.device_features(device_id)) { - Ok(features) => features, - Err(err) => handle_error_fatal(err, "wgpuDeviceHasFeature"), - }; + let device_features = context.device_features(device_id); let feature = match conv::map_feature(feature) { Some(feature) => feature, @@ -2554,11 +2582,10 @@ pub unsafe extern "C" fn wgpuDeviceHasFeature( #[no_mangle] pub unsafe extern "C" fn wgpuDevicePopErrorScope( device: native::WGPUDevice, - callback: native::WGPUErrorCallback, - userdata: *mut ::std::os::raw::c_void, -) { + callback_info: native::WGPUPopErrorScopeCallbackInfo, +) -> native::WGPUFuture { let device = device.as_ref().expect("invalid device"); - let callback = callback.expect("invalid callback"); + let callback = callback_info.callback.expect("invalid callback"); let mut error_sink = device.error_sink.lock(); let scope = error_sink.scopes.pop().unwrap(); @@ -2572,18 +2599,31 @@ pub unsafe extern "C" fn wgpuDevicePopErrorScope( crate::Error::DeviceLost { .. } => unreachable!(), }; - let msg = CString::new(error.to_string()).unwrap(); + let msg = error.to_string(); unsafe { - callback(typ, msg.as_ptr(), userdata); + callback( + native::WGPUPopErrorScopeStatus_Success, + typ, + str_into_string_view(&msg), + callback_info.userdata1, + callback_info.userdata2, + ); }; } None => { - let msg = CString::default(); unsafe { - callback(native::WGPUErrorType_NoError, msg.as_ptr(), userdata); + callback( + native::WGPUPopErrorScopeStatus_Success, + native::WGPUErrorType_NoError, + EMPTY_STRING, + callback_info.userdata1, + callback_info.userdata2, + ); }; } }; + + return NULL_FUTURE; } #[no_mangle] @@ -2604,7 +2644,7 @@ pub unsafe extern "C" fn wgpuDevicePushErrorScope( } #[no_mangle] -pub unsafe extern "C" fn wgpuDeviceReference(device: native::WGPUDevice) { +pub unsafe extern "C" fn wgpuDeviceAddRef(device: native::WGPUDevice) { assert!(!device.is_null(), "invalid device"); Arc::increment_strong_count(device); } @@ -2626,12 +2666,12 @@ pub unsafe extern "C" fn wgpuInstanceCreateSurface( let create_surface_params = follow_chain!( map_surface((descriptor), - WGPUSType_SurfaceDescriptorFromWindowsHWND => native::WGPUSurfaceDescriptorFromWindowsHWND, - WGPUSType_SurfaceDescriptorFromXcbWindow => native::WGPUSurfaceDescriptorFromXcbWindow, - WGPUSType_SurfaceDescriptorFromXlibWindow => native::WGPUSurfaceDescriptorFromXlibWindow, - WGPUSType_SurfaceDescriptorFromWaylandSurface => native::WGPUSurfaceDescriptorFromWaylandSurface, - WGPUSType_SurfaceDescriptorFromMetalLayer => native::WGPUSurfaceDescriptorFromMetalLayer, - WGPUSType_SurfaceDescriptorFromAndroidNativeWindow => native::WGPUSurfaceDescriptorFromAndroidNativeWindow) + WGPUSType_SurfaceSourceWindowsHWND => native::WGPUSurfaceSourceWindowsHWND, + WGPUSType_SurfaceSourceXCBWindow => native::WGPUSurfaceSourceXCBWindow, + WGPUSType_SurfaceSourceXlibWindow => native::WGPUSurfaceSourceXlibWindow, + WGPUSType_SurfaceSourceWaylandSurface => native::WGPUSurfaceSourceWaylandSurface, + WGPUSType_SurfaceSourceMetalLayer => native::WGPUSurfaceSourceMetalLayer, + WGPUSType_SurfaceSourceAndroidNativeWindow => native::WGPUSurfaceSourceAndroidNativeWindow) ); let surface_id = match create_surface_params { @@ -2662,12 +2702,11 @@ pub unsafe extern "C" fn wgpuInstanceCreateSurface( pub unsafe extern "C" fn wgpuInstanceRequestAdapter( instance: native::WGPUInstance, options: Option<&native::WGPURequestAdapterOptions>, - callback: native::WGPUInstanceRequestAdapterCallback, - userdata: *mut std::os::raw::c_void, -) { + callback_info: native::WGPURequestAdapterCallbackInfo, +) -> native::WGPUFuture { let instance = instance.as_ref().expect("invalid instance"); let context = &instance.context; - let callback = callback.expect("invalid callback"); + let callback = callback_info.callback.expect("invalid callback"); let (desc, inputs) = match options { Some(options) => ( @@ -2682,67 +2721,62 @@ pub unsafe extern "C" fn wgpuInstanceRequestAdapter( force_fallback_adapter: options.forceFallbackAdapter != 0, compatible_surface: options.compatibleSurface.as_ref().map(|surface| surface.id), }, - wgc::instance::AdapterInputs::Mask( - match options.backendType { - native::WGPUBackendType_Undefined => wgt::Backends::all(), - native::WGPUBackendType_Null => wgt::Backends::empty(), - native::WGPUBackendType_WebGPU => wgt::Backends::BROWSER_WEBGPU, - native::WGPUBackendType_D3D12 => wgt::Backends::DX12, - native::WGPUBackendType_Metal => wgt::Backends::METAL, - native::WGPUBackendType_Vulkan => wgt::Backends::VULKAN, - native::WGPUBackendType_OpenGL => wgt::Backends::GL, - native::WGPUBackendType_OpenGLES => wgt::Backends::GL, - native::WGPUBackendType_D3D11 => { - callback( - native::WGPURequestAdapterStatus_Error, - std::ptr::null_mut(), - "unsupported backend type: d3d11".as_ptr() as _, - userdata, - ); - return; - } - backend_type => panic!("invalid backend type: 0x{backend_type:08X}"), - }, - |_| None, - ), - ), - None => ( - wgt::RequestAdapterOptions::default(), - wgc::instance::AdapterInputs::Mask(wgt::Backends::all(), |_| None), + match options.backendType { + native::WGPUBackendType_Undefined => wgt::Backends::all(), + native::WGPUBackendType_Null => wgt::Backends::empty(), + native::WGPUBackendType_WebGPU => wgt::Backends::BROWSER_WEBGPU, + native::WGPUBackendType_D3D12 => wgt::Backends::DX12, + native::WGPUBackendType_Metal => wgt::Backends::METAL, + native::WGPUBackendType_Vulkan => wgt::Backends::VULKAN, + native::WGPUBackendType_OpenGL => wgt::Backends::GL, + native::WGPUBackendType_OpenGLES => wgt::Backends::GL, + native::WGPUBackendType_D3D11 => { + callback( + native::WGPURequestAdapterStatus_Error, + std::ptr::null_mut(), + str_into_string_view("unsupported backend type: d3d11"), + callback_info.userdata1, + callback_info.userdata2, + ); + return NULL_FUTURE; + } + backend_type => panic!("invalid backend type: 0x{backend_type:08X}"), + }, ), + None => (wgt::RequestAdapterOptions::default(), wgt::Backends::all()), }; - match context.request_adapter(&desc, inputs) { + match context.request_adapter(&desc, inputs, None) { Ok(adapter_id) => { - let message = CString::default(); callback( native::WGPURequestAdapterStatus_Success, Arc::into_raw(Arc::new(WGPUAdapterImpl { context: context.clone(), id: adapter_id, })), - message.as_ptr(), - userdata, + EMPTY_STRING, + callback_info.userdata1, + callback_info.userdata2, ); } Err(err) => { - let message = CString::new(format_error(&err)).unwrap(); + let message = format_error(&err); callback( match err { wgc::instance::RequestAdapterError::NotFound => { native::WGPURequestAdapterStatus_Unavailable } - wgc::instance::RequestAdapterError::InvalidSurface(_) => { - native::WGPURequestAdapterStatus_Error - } _ => native::WGPURequestAdapterStatus_Unknown, }, std::ptr::null_mut(), - message.as_ptr(), - userdata, + str_into_string_view(&message), + callback_info.userdata1, + callback_info.userdata2, ); } }; + + return NULL_FUTURE; } #[no_mangle] @@ -2755,11 +2789,10 @@ pub unsafe extern "C" fn wgpuInstanceEnumerateAdapters( let context = &instance.context; let inputs = match options { - Some(options) => wgc::instance::AdapterInputs::Mask( - map_instance_backend_flags(options.backends as native::WGPUInstanceBackend), - |_| None, - ), - None => wgc::instance::AdapterInputs::Mask(wgt::Backends::all(), |_| None), + Some(options) => { + map_instance_backend_flags(options.backends as native::WGPUInstanceBackend) + } + None => wgt::Backends::all(), }; let result = context.enumerate_adapters(inputs); @@ -2780,16 +2813,14 @@ pub unsafe extern "C" fn wgpuInstanceEnumerateAdapters( } else { // Drop all the adapters when only counting length. - result - .iter() - .for_each(|id| gfx_select!(id => context.adapter_drop(*id))); + result.iter().for_each(|id| context.adapter_drop(*id)); } count } #[no_mangle] -pub unsafe extern "C" fn wgpuInstanceReference(instance: native::WGPUInstance) { +pub unsafe extern "C" fn wgpuInstanceAddRef(instance: native::WGPUInstance) { assert!(!instance.is_null(), "invalid instance"); Arc::increment_strong_count(instance); } @@ -2802,7 +2833,7 @@ pub unsafe extern "C" fn wgpuInstanceRelease(instance: native::WGPUInstance) { // PipelineLayout methods #[no_mangle] -pub unsafe extern "C" fn wgpuPipelineLayoutReference(pipeline_layout: native::WGPUPipelineLayout) { +pub unsafe extern "C" fn wgpuPipelineLayoutAddRef(pipeline_layout: native::WGPUPipelineLayout) { assert!(!pipeline_layout.is_null(), "invalid pipeline layout"); Arc::increment_strong_count(pipeline_layout); } @@ -2834,7 +2865,7 @@ pub unsafe extern "C" fn wgpuQuerySetGetType( } #[no_mangle] -pub unsafe extern "C" fn wgpuQuerySetReference(query_set: native::WGPUQuerySet) { +pub unsafe extern "C" fn wgpuQuerySetAddRef(query_set: native::WGPUQuerySet) { assert!(!query_set.is_null(), "invalid query set"); Arc::increment_strong_count(query_set); } @@ -2849,25 +2880,27 @@ pub unsafe extern "C" fn wgpuQuerySetRelease(query_set: native::WGPUQuerySet) { #[no_mangle] pub unsafe extern "C" fn wgpuQueueOnSubmittedWorkDone( queue: native::WGPUQueue, - callback: native::WGPUQueueOnSubmittedWorkDoneCallback, - userdata: *mut ::std::os::raw::c_void, -) { + callback_info: native::WGPUQueueWorkDoneCallbackInfo, +) -> native::WGPUFuture { let (queue_id, context) = { let queue = queue.as_ref().expect("invalid queue"); (queue.queue.id, &queue.queue.context) }; - let callback = callback.expect("invalid callback"); - let userdata = utils::Userdata::new(userdata); + let callback = callback_info.callback.expect("invalid callback"); + let userdata = new_userdata!(callback_info); let closure = wgc::device::queue::SubmittedWorkDoneClosure::from_rust(Box::new(move || { - callback(native::WGPUQueueWorkDoneStatus_Success, userdata.as_ptr()); + callback( + native::WGPUQueueWorkDoneStatus_Success, + userdata.get_1(), + userdata.get_2(), + ); })); - if let Err(cause) = - gfx_select!(queue_id => context.queue_on_submitted_work_done(queue_id, closure)) - { - handle_error_fatal(cause, "wgpuQueueOnSubmittedWorkDone"); - }; + context.queue_on_submitted_work_done(queue_id, closure); + + // TODO: Properly handle futures. + NULL_FUTURE } #[no_mangle] @@ -2890,8 +2923,8 @@ pub unsafe extern "C" fn wgpuQueueSubmit( }) .collect::>(); - if let Err(cause) = gfx_select!(queue_id => context.queue_submit(queue_id, &command_buffers)) { - handle_error_fatal(cause, "wgpuQueueSubmit"); + if let Err(cause) = context.queue_submit(queue_id, &command_buffers) { + handle_error_fatal(cause.1, "wgpuQueueSubmit"); } } @@ -2909,12 +2942,12 @@ pub unsafe extern "C" fn wgpuQueueWriteBuffer( }; let buffer_id = buffer.as_ref().expect("invalid buffer").id; - if let Err(cause) = gfx_select!(queue_id => context.queue_write_buffer( + if let Err(cause) = context.queue_write_buffer( queue_id, buffer_id, buffer_offset, - make_slice(data, data_size) - )) { + make_slice(data, data_size), + ) { handle_error(error_sink, cause, None, "wgpuQueueWriteBuffer"); } } @@ -2922,10 +2955,10 @@ pub unsafe extern "C" fn wgpuQueueWriteBuffer( #[no_mangle] pub unsafe extern "C" fn wgpuQueueWriteTexture( queue: native::WGPUQueue, - destination: Option<&native::WGPUImageCopyTexture>, + destination: Option<&native::WGPUTexelCopyTextureInfo>, data: *const u8, // TODO: Check - this might not follow the header data_size: usize, - data_layout: Option<&native::WGPUTextureDataLayout>, + data_layout: Option<&native::WGPUTexelCopyBufferLayout>, write_size: Option<&native::WGPUExtent3D>, ) { let (queue_id, context, error_sink) = { @@ -2933,19 +2966,19 @@ pub unsafe extern "C" fn wgpuQueueWriteTexture( (queue.queue.id, &queue.queue.context, &queue.error_sink) }; - if let Err(cause) = gfx_select!(queue_id => context.queue_write_texture( + if let Err(cause) = context.queue_write_texture( queue_id, &conv::map_image_copy_texture(destination.expect("invalid destination")), make_slice(data, data_size), &conv::map_texture_data_layout(data_layout.expect("invalid data layout")), - &conv::map_extent3d(write_size.expect("invalid write size")) - )) { + &conv::map_extent3d(write_size.expect("invalid write size")), + ) { handle_error(error_sink, cause, None, "wgpuQueueWriteTexture"); } } #[no_mangle] -pub unsafe extern "C" fn wgpuQueueReference(queue: native::WGPUQueue) { +pub unsafe extern "C" fn wgpuQueueAddRef(queue: native::WGPUQueue) { assert!(!queue.is_null(), "invalid queue"); Arc::increment_strong_count(queue); } @@ -2958,7 +2991,7 @@ pub unsafe extern "C" fn wgpuQueueRelease(queue: native::WGPUQueue) { // RenderBundle methods #[no_mangle] -pub unsafe extern "C" fn wgpuRenderBundleReference(render_bundle: native::WGPURenderBundle) { +pub unsafe extern "C" fn wgpuRenderBundleAddRef(render_bundle: native::WGPURenderBundle) { assert!(!render_bundle.is_null(), "invalid render bundle"); Arc::increment_strong_count(render_bundle); } @@ -3069,12 +3102,12 @@ pub unsafe extern "C" fn wgpuRenderBundleEncoderFinish( let desc = match descriptor { Some(descriptor) => wgt::RenderBundleDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), }, None => wgt::RenderBundleDescriptor::default(), }; - let (render_bundle_id, error) = gfx_select!(encoder.parent() => context.render_bundle_encoder_finish(*encoder, &desc, None)); + let (render_bundle_id, error) = context.render_bundle_encoder_finish(*encoder, &desc, None); if let Some(cause) = error { handle_error_fatal(cause, "wgpuRenderBundleEncoderFinish"); } @@ -3087,40 +3120,49 @@ pub unsafe extern "C" fn wgpuRenderBundleEncoderFinish( #[no_mangle] pub unsafe extern "C" fn wgpuRenderBundleEncoderInsertDebugMarker( - bundle: native::WGPURenderBundleEncoder, - marker_label: *const std::ffi::c_char, + _bundle: native::WGPURenderBundleEncoder, + _marker_label: native::WGPUStringView, ) { - let bundle = bundle.as_ref().expect("invalid render bundle"); - let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); - let encoder = encoder.expect("invalid render bundle"); - let encoder = encoder.as_mut().unwrap(); + // These functions are not implemented in wgpu-core, and the API is incompatible with the new WGPUStringView. + // Commenting out until it's actually implemented. + + // let bundle = bundle.as_ref().expect("invalid render bundle"); + // let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); + // let encoder = encoder.expect("invalid render bundle"); + // let encoder = encoder.as_mut().unwrap(); - bundle_ffi::wgpu_render_bundle_insert_debug_marker(encoder, marker_label); + // bundle_ffi::wgpu_render_bundle_insert_debug_marker(encoder, marker_label); } #[no_mangle] pub unsafe extern "C" fn wgpuRenderBundleEncoderPopDebugGroup( - bundle: native::WGPURenderBundleEncoder, + _bundle: native::WGPURenderBundleEncoder, ) { - let bundle = bundle.as_ref().expect("invalid render bundle"); - let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); - let encoder = encoder.expect("invalid render bundle"); - let encoder = encoder.as_mut().unwrap(); + // These functions are not implemented in wgpu-core, and the API is incompatible with the new WGPUStringView. + // Commenting out until it's actually implemented. - bundle_ffi::wgpu_render_bundle_pop_debug_group(encoder); + // let bundle = bundle.as_ref().expect("invalid render bundle"); + // let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); + // let encoder = encoder.expect("invalid render bundle"); + // let encoder = encoder.as_mut().unwrap(); + + // bundle_ffi::wgpu_render_bundle_pop_debug_group(encoder); } #[no_mangle] pub unsafe extern "C" fn wgpuRenderBundleEncoderPushDebugGroup( - bundle: native::WGPURenderBundleEncoder, - group_label: *const std::ffi::c_char, + _bundle: native::WGPURenderBundleEncoder, + _group_label: native::WGPUStringView, ) { - let bundle = bundle.as_ref().expect("invalid render bundle"); - let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); - let encoder = encoder.expect("invalid render bundle"); - let encoder = encoder.as_mut().unwrap(); + // These functions are not implemented in wgpu-core, and the API is incompatible with the new WGPUStringView. + // Commenting out until it's actually implemented. - bundle_ffi::wgpu_render_bundle_push_debug_group(encoder, group_label); + // let bundle = bundle.as_ref().expect("invalid render bundle"); + // let encoder = bundle.encoder.as_mut().expect("invalid render bundle"); + // let encoder = encoder.expect("invalid render bundle"); + // let encoder = encoder.as_mut().unwrap(); + + // bundle_ffi::wgpu_render_bundle_push_debug_group(encoder, group_label); } #[no_mangle] @@ -3141,7 +3183,7 @@ pub unsafe extern "C" fn wgpuRenderBundleEncoderSetBindGroup( bundle_ffi::wgpu_render_bundle_set_bind_group( encoder, group_index, - bind_group_id, + Some(bind_group_id), dynamic_offsets, dynamic_offset_count, ); @@ -3217,7 +3259,7 @@ pub unsafe extern "C" fn wgpuRenderBundleEncoderSetVertexBuffer( } #[no_mangle] -pub unsafe extern "C" fn wgpuRenderBundleEncoderReference( +pub unsafe extern "C" fn wgpuRenderBundleEncoderAddRef( render_bundle_encoder: native::WGPURenderBundleEncoder, ) { assert!( @@ -3245,9 +3287,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderBeginOcclusionQuery( query_index: u32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.begin_occlusion_query(&pass.context, query_index) { + match pass + .context + .render_pass_begin_occlusion_query(encoder, query_index) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3267,10 +3312,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderDraw( first_instance: u32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.draw( - &pass.context, + match pass.context.render_pass_draw( + encoder, vertex_count, instance_count, first_vertex, @@ -3291,10 +3336,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderDrawIndexed( first_instance: u32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.draw_indexed( - &pass.context, + match pass.context.render_pass_draw_indexed( + encoder, index_count, instance_count, first_index, @@ -3322,9 +3367,13 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderDrawIndexedIndirect( .as_ref() .expect("invalid indirect buffer") .id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.draw_indexed_indirect(&pass.context, indirect_buffer_id, indirect_offset) { + match pass.context.render_pass_draw_indexed_indirect( + encoder, + indirect_buffer_id, + indirect_offset, + ) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3346,9 +3395,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderDrawIndirect( .as_ref() .expect("invalid indirect buffer") .id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.draw_indirect(&pass.context, indirect_buffer_id, indirect_offset) { + match pass + .context + .render_pass_draw_indirect(encoder, indirect_buffer_id, indirect_offset) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3362,9 +3414,9 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderDrawIndirect( #[no_mangle] pub unsafe extern "C" fn wgpuRenderPassEncoderEnd(pass: native::WGPURenderPassEncoder) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.end(&pass.context) { + match pass.context.render_pass_end(encoder) { Ok(()) => (), Err(cause) => handle_error(&pass.error_sink, cause, None, "wgpuRenderPassEncoderEnd"), } @@ -3375,9 +3427,9 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderEndOcclusionQuery( pass: native::WGPURenderPassEncoder, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.end_occlusion_query(&pass.context) { + match pass.context.render_pass_end_occlusion_query(encoder) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3399,9 +3451,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderExecuteBundles( .iter() .map(|v| v.as_ref().expect("invalid render bundle").id) .collect::>(); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.execute_bundles(&pass.context, &bundle_ids) { + match pass + .context + .render_pass_execute_bundles(encoder, &bundle_ids) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3415,14 +3470,14 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderExecuteBundles( #[no_mangle] pub unsafe extern "C" fn wgpuRenderPassEncoderInsertDebugMarker( pass: native::WGPURenderPassEncoder, - marker_label: *const std::ffi::c_char, + marker_label: native::WGPUStringView, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.insert_debug_marker( - &pass.context, - CStr::from_ptr(marker_label).to_str().unwrap(), + match pass.context.render_pass_insert_debug_marker( + encoder, + string_view_into_str(marker_label).unwrap_or(""), 0, ) { Ok(()) => (), @@ -3438,9 +3493,9 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderInsertDebugMarker( #[no_mangle] pub unsafe extern "C" fn wgpuRenderPassEncoderPopDebugGroup(pass: native::WGPURenderPassEncoder) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.pop_debug_group(&pass.context) { + match pass.context.render_pass_pop_debug_group(encoder) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3454,14 +3509,14 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderPopDebugGroup(pass: native::WGPURe #[no_mangle] pub unsafe extern "C" fn wgpuRenderPassEncoderPushDebugGroup( pass: native::WGPURenderPassEncoder, - group_label: *const std::ffi::c_char, + group_label: native::WGPUStringView, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.push_debug_group( - &pass.context, - CStr::from_ptr(group_label).to_str().unwrap(), + match pass.context.render_pass_push_debug_group( + encoder, + string_view_into_str(group_label).unwrap_or(""), 0, ) { Ok(()) => (), @@ -3485,12 +3540,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetBindGroup( let pass = pass.as_ref().expect("invalid render pass"); // TODO: as per webgpu.h bindgroup is nullable let bind_group_id = bind_group.as_ref().expect("invalid bind group").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_bind_group( - &pass.context, + match pass.context.render_pass_set_bind_group( + encoder, group_index, - bind_group_id, + Some(bind_group_id), make_slice(dynamic_offsets, dynamic_offset_count), ) { Ok(()) => (), @@ -3509,12 +3564,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetBlendConstant( color: Option<&native::WGPUColor>, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_blend_constant( - &pass.context, - conv::map_color(color.expect("invalid color")), - ) { + match pass + .context + .render_pass_set_blend_constant(encoder, conv::map_color(color.expect("invalid color"))) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3535,10 +3590,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetIndexBuffer( ) { let pass = pass.as_ref().expect("invalid render pass"); let buffer_id = buffer.as_ref().expect("invalid buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_index_buffer( - &pass.context, + match pass.context.render_pass_set_index_buffer( + encoder, buffer_id, conv::map_index_format(index_format).expect("invalid index format"), offset, @@ -3568,9 +3623,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetPipeline( .as_ref() .expect("invalid render pipeline") .id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_pipeline(&pass.context, render_pipeline_id) { + match pass + .context + .render_pass_set_pipeline(encoder, render_pipeline_id) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3590,9 +3648,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetScissorRect( height: u32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_scissor_rect(&pass.context, x, y, width, height) { + match pass + .context + .render_pass_set_scissor_rect(encoder, x, y, width, height) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3609,9 +3670,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetStencilReference( reference: u32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_stencil_reference(&pass.context, reference) { + match pass + .context + .render_pass_set_stencil_reference(encoder, reference) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3633,10 +3697,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetVertexBuffer( let pass = pass.as_ref().expect("invalid render pass"); // TODO: as per webgpu.h buffer is nullable let buffer_id = buffer.as_ref().expect("invalid buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_vertex_buffer( - &pass.context, + match pass.context.render_pass_set_vertex_buffer( + encoder, slot, buffer_id, offset, @@ -3667,9 +3731,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetViewport( max_depth: f32, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_viewport(&pass.context, x, y, width, height, min_depth, max_depth) { + match pass + .context + .render_pass_set_viewport(encoder, x, y, width, height, min_depth, max_depth) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -3681,7 +3748,7 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetViewport( } #[no_mangle] -pub unsafe extern "C" fn wgpuRenderPassEncoderReference( +pub unsafe extern "C" fn wgpuRenderPassEncoderAddRef( render_pass_encoder: native::WGPURenderPassEncoder, ) { assert!( @@ -3716,7 +3783,8 @@ pub unsafe extern "C" fn wgpuRenderPipelineGetBindGroupLayout( &render_pipeline.error_sink, ) }; - let (bind_group_layout_id, error) = gfx_select!(render_pipeline_id => context.render_pipeline_get_bind_group_layout(render_pipeline_id, group_index, None)); + let (bind_group_layout_id, error) = + context.render_pipeline_get_bind_group_layout(render_pipeline_id, group_index, None); if let Some(cause) = error { handle_error( error_sink, @@ -3733,7 +3801,7 @@ pub unsafe extern "C" fn wgpuRenderPipelineGetBindGroupLayout( } #[no_mangle] -pub unsafe extern "C" fn wgpuRenderPipelineReference(render_pipeline: native::WGPURenderPipeline) { +pub unsafe extern "C" fn wgpuRenderPipelineAddRef(render_pipeline: native::WGPURenderPipeline) { assert!(!render_pipeline.is_null(), "invalid render pipeline"); Arc::increment_strong_count(render_pipeline); } @@ -3746,7 +3814,7 @@ pub unsafe extern "C" fn wgpuRenderPipelineRelease(render_pipeline: native::WGPU // Sampler methods #[no_mangle] -pub unsafe extern "C" fn wgpuSamplerReference(sampler: native::WGPUSampler) { +pub unsafe extern "C" fn wgpuSamplerAddRef(sampler: native::WGPUSampler) { assert!(!sampler.is_null(), "invalid sampler"); Arc::increment_strong_count(sampler); } @@ -3759,7 +3827,7 @@ pub unsafe extern "C" fn wgpuSamplerRelease(sampler: native::WGPUSampler) { // ShaderModule methods #[no_mangle] -pub unsafe extern "C" fn wgpuShaderModuleReference(shader_module: native::WGPUShaderModule) { +pub unsafe extern "C" fn wgpuShaderModuleAddRef(shader_module: native::WGPUShaderModule) { assert!(!shader_module.is_null(), "invalid shader module"); Arc::increment_strong_count(shader_module); } @@ -3789,13 +3857,11 @@ pub unsafe extern "C" fn wgpuSurfaceConfigure( WGPUSType_SurfaceConfigurationExtras => native::WGPUSurfaceConfigurationExtras )); - match wgc::gfx_select!(device.id => context.surface_configure(surface.id, device.id, &surface_config)) - { + match context.surface_configure(surface.id, device.id, &surface_config) { Some(cause) => handle_error_fatal(cause, "wgpuSurfaceConfigure"), None => { let mut surface_data_guard = surface.data.lock(); *surface_data_guard = Some(SurfaceData { - device_id: device.id, error_sink: device.error_sink.clone(), texture_data: TextureData { usage: config.usage, @@ -3830,8 +3896,7 @@ pub unsafe extern "C" fn wgpuSurfaceGetCapabilities( let surface_id = surface.as_ref().expect("invalid surface").id; let capabilities = capabilities.expect("invalid return pointer \"capabilities\""); - let caps = match wgc::gfx_select!(adapter_id => context.surface_get_capabilities(surface_id, adapter_id)) - { + let caps = match context.surface_get_capabilities(surface_id, adapter_id) { Ok(caps) => caps, Err(wgc::instance::GetSurfaceSupportError::Unsupported) => { wgt::SurfaceCapabilities::default() @@ -3840,7 +3905,7 @@ pub unsafe extern "C" fn wgpuSurfaceGetCapabilities( }; capabilities.usages = - conv::to_native_texture_usage_flags(caps.usages) as native::WGPUTextureUsageFlags; + conv::to_native_texture_usage_flags(caps.usages) as native::WGPUTextureUsage; let formats = caps .formats @@ -3912,25 +3977,22 @@ pub unsafe extern "C" fn wgpuSurfaceGetCurrentTexture( ), }; - match wgc::gfx_select!(surface_data.device_id => context.surface_get_current_texture(surface.id, None)) - { + match context.surface_get_current_texture(surface.id, None) { Ok(wgc::present::SurfaceOutput { status, texture_id }) => { surface .has_surface_presented .store(false, atomic::Ordering::SeqCst); surface_texture.status = match status { - wgt::SurfaceStatus::Good => native::WGPUSurfaceGetCurrentTextureStatus_Success, + wgt::SurfaceStatus::Good => { + native::WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal + } wgt::SurfaceStatus::Suboptimal => { - native::WGPUSurfaceGetCurrentTextureStatus_Success + native::WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal } wgt::SurfaceStatus::Timeout => native::WGPUSurfaceGetCurrentTextureStatus_Timeout, wgt::SurfaceStatus::Outdated => native::WGPUSurfaceGetCurrentTextureStatus_Outdated, wgt::SurfaceStatus::Lost => native::WGPUSurfaceGetCurrentTextureStatus_Lost, }; - surface_texture.suboptimal = match status { - wgt::SurfaceStatus::Suboptimal => true as native::WGPUBool, - _ => false as native::WGPUBool, - }; surface_texture.texture = match texture_id { Some(texture_id) => Arc::into_raw(Arc::new(WGPUTextureImpl { context: context.clone(), @@ -3951,16 +4013,8 @@ pub unsafe extern "C" fn wgpuSurfaceGetCurrentTexture( pub unsafe extern "C" fn wgpuSurfacePresent(surface: native::WGPUSurface) { let surface = surface.as_ref().expect("invalid surface"); let context = &surface.context; - let surface_data_guard = surface.data.lock(); - let surface_data = match surface_data_guard.as_ref() { - Some(surface_data) => surface_data, - None => handle_error_fatal( - wgc::present::SurfaceError::NotConfigured, - "wgpuSurfacePresent", - ), - }; - match wgc::gfx_select!(surface_data.device_id => context.surface_present(surface.id)) { + match context.surface_present(surface.id) { Ok(_status) => surface .has_surface_presented .store(true, atomic::Ordering::SeqCst), @@ -3979,7 +4033,7 @@ pub unsafe extern "C" fn wgpuSurfaceUnconfigure(surface: native::WGPUSurface) { } #[no_mangle] -pub unsafe extern "C" fn wgpuSurfaceReference(surface: native::WGPUSurface) { +pub unsafe extern "C" fn wgpuSurfaceAddRef(surface: native::WGPUSurface) { assert!(!surface.is_null(), "invalid surface"); Arc::increment_strong_count(surface); } @@ -4025,37 +4079,49 @@ pub unsafe extern "C" fn wgpuTextureCreateView( texture: native::WGPUTexture, descriptor: Option<&native::WGPUTextureViewDescriptor>, ) -> native::WGPUTextureView { - let (texture_id, context, error_sink) = { + let (texture_id, context, error_sink, texture_usage) = { let texture = texture.as_ref().expect("invalid texture"); - (texture.id, &texture.context, &texture.error_sink) + ( + texture.id, + &texture.context, + &texture.error_sink, + texture.data.usage, + ) }; let desc = match descriptor { - Some(descriptor) => wgc::resource::TextureViewDescriptor { - label: ptr_into_label(descriptor.label), - format: conv::map_texture_format(descriptor.format), - dimension: conv::map_texture_view_dimension(descriptor.dimension), - range: wgt::ImageSubresourceRange { - aspect: conv::map_texture_aspect(descriptor.aspect), - base_mip_level: descriptor.baseMipLevel, - mip_level_count: match descriptor.mipLevelCount { - 0 => panic!("invalid mipLevelCount"), - native::WGPU_MIP_LEVEL_COUNT_UNDEFINED => None, - _ => Some(descriptor.mipLevelCount), - }, - base_array_layer: descriptor.baseArrayLayer, - array_layer_count: match descriptor.arrayLayerCount { - 0 => panic!("invalid arrayLayerCount"), - native::WGPU_ARRAY_LAYER_COUNT_UNDEFINED => None, - _ => Some(descriptor.arrayLayerCount), + Some(descriptor) => { + // TODO: Pass usage to texture view creation when wgpu-core supports it. + if descriptor.usage != 0 && (descriptor.usage & texture_usage) != descriptor.usage { + panic!("Texture view usage must be subset of texture's usage") + } + + wgc::resource::TextureViewDescriptor { + label: string_view_into_label(descriptor.label), + format: conv::map_texture_format(descriptor.format), + dimension: conv::map_texture_view_dimension(descriptor.dimension), + range: wgt::ImageSubresourceRange { + aspect: conv::map_texture_aspect(descriptor.aspect) + .unwrap_or(wgt::TextureAspect::All), + base_mip_level: descriptor.baseMipLevel, + mip_level_count: match descriptor.mipLevelCount { + 0 => panic!("invalid mipLevelCount"), + native::WGPU_MIP_LEVEL_COUNT_UNDEFINED => None, + _ => Some(descriptor.mipLevelCount), + }, + base_array_layer: descriptor.baseArrayLayer, + array_layer_count: match descriptor.arrayLayerCount { + 0 => panic!("invalid arrayLayerCount"), + native::WGPU_ARRAY_LAYER_COUNT_UNDEFINED => None, + _ => Some(descriptor.arrayLayerCount), + }, }, - }, - }, + } + } None => wgc::resource::TextureViewDescriptor::default(), }; - let (texture_view_id, error) = - gfx_select!(texture_id => context.texture_create_view(texture_id, &desc, None)); + let (texture_view_id, error) = context.texture_create_view(texture_id, &desc, None); if let Some(cause) = error { handle_error(error_sink, cause, None, "wgpuTextureCreateView"); } @@ -4074,7 +4140,7 @@ pub unsafe extern "C" fn wgpuTextureDestroy(texture: native::WGPUTexture) { }; // Per spec, no error to report. Even calling destroy multiple times is valid. - let _ = gfx_select!(texture_id => context.texture_destroy(texture_id)); + let _ = context.texture_destroy(texture_id); } #[no_mangle] @@ -4120,7 +4186,7 @@ pub unsafe extern "C" fn wgpuTextureGetSampleCount(texture: native::WGPUTexture) #[no_mangle] pub unsafe extern "C" fn wgpuTextureGetUsage( texture: native::WGPUTexture, -) -> native::WGPUTextureUsageFlags { +) -> native::WGPUTextureUsage { let texture = texture.as_ref().expect("invalid texture"); texture.data.usage } @@ -4132,7 +4198,7 @@ pub unsafe extern "C" fn wgpuTextureGetWidth(texture: native::WGPUTexture) -> u3 } #[no_mangle] -pub unsafe extern "C" fn wgpuTextureReference(texture: native::WGPUTexture) { +pub unsafe extern "C" fn wgpuTextureAddRef(texture: native::WGPUTexture) { assert!(!texture.is_null(), "invalid texture"); Arc::increment_strong_count(texture); } @@ -4145,7 +4211,7 @@ pub unsafe extern "C" fn wgpuTextureRelease(texture: native::WGPUTexture) { // TextureView methods #[no_mangle] -pub unsafe extern "C" fn wgpuTextureViewReference(texture_view: native::WGPUTextureView) { +pub unsafe extern "C" fn wgpuTextureViewAddRef(texture_view: native::WGPUTextureView) { assert!(!texture_view.is_null(), "invalid texture"); Arc::increment_strong_count(texture_view); } @@ -4187,9 +4253,9 @@ pub unsafe extern "C" fn wgpuQueueSubmitForIndex( }) .collect::>(); - match gfx_select!(queue_id => context.queue_submit(queue_id, &command_buffers)) { - Ok(submission_index) => submission_index.index, - Err(cause) => handle_error_fatal(cause, "wgpuQueueSubmitForIndex"), + match context.queue_submit(queue_id, &command_buffers) { + Ok(submission_index) => submission_index, + Err(cause) => handle_error_fatal(cause.1, "wgpuQueueSubmitForIndex"), } } @@ -4197,7 +4263,7 @@ pub unsafe extern "C" fn wgpuQueueSubmitForIndex( pub unsafe extern "C" fn wgpuDevicePoll( device: native::WGPUDevice, wait: bool, - wrapped_submission_index: Option<&native::WGPUWrappedSubmissionIndex>, + submission_index: Option<&native::WGPUSubmissionIndex>, ) -> bool { let (device_id, context) = { let device = device.as_ref().expect("invalid device"); @@ -4205,24 +4271,14 @@ pub unsafe extern "C" fn wgpuDevicePoll( }; let maintain = match wait { - true => match wrapped_submission_index { - Some(index) => { - wgt::Maintain::WaitForSubmissionIndex(wgc::device::queue::WrappedSubmissionIndex { - queue_id: index - .queue - .as_ref() - .expect("invalid queue for wrapped submission index") - .queue - .id, - index: index.submissionIndex, - }) - } + true => match submission_index { + Some(index) => wgt::Maintain::WaitForSubmissionIndex(*index), None => wgt::Maintain::Wait, }, false => wgt::Maintain::Poll, }; - match gfx_select!(device_id => context.device_poll(device_id, maintain)) { + match context.device_poll(device_id, maintain) { Ok(queue_empty) => queue_empty, Err(cause) => { handle_error_fatal(cause, "wgpuDevicePoll"); @@ -4242,7 +4298,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModuleSpirV( let descriptor = descriptor.expect("invalid descriptor"); let desc = wgc::pipeline::ShaderModuleDescriptor { - label: ptr_into_label(descriptor.label), + label: string_view_into_label(descriptor.label), shader_bound_checks: unsafe { wgt::ShaderBoundChecks::unchecked() }, }; @@ -4250,7 +4306,8 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModuleSpirV( descriptor.source, descriptor.sourceSize as usize, )); - let (shader_module_id, error) = gfx_select!(device_id => context.device_create_shader_module_spirv(device_id, &desc, source, None)); + let (shader_module_id, error) = + context.device_create_shader_module_spirv(device_id, &desc, source, None); if let Some(cause) = error { handle_error( error_sink, @@ -4269,17 +4326,17 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModuleSpirV( #[no_mangle] pub unsafe extern "C" fn wgpuRenderPassEncoderSetPushConstants( pass: native::WGPURenderPassEncoder, - stages: native::WGPUShaderStageFlags, + stages: native::WGPUShaderStage, offset: u32, size_bytes: u32, data: *const u8, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_push_constants( - &pass.context, - wgt::ShaderStages::from_bits(stages).expect("invalid shader stage"), + match pass.context.render_pass_set_push_constants( + encoder, + from_u64_bits(stages).expect("invalid shader stage"), offset, make_slice(data, size_bytes as usize), ) { @@ -4301,9 +4358,13 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetPushConstants( data: *const u8, ) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.set_push_constants(&pass.context, offset, make_slice(data, size_bytes as usize)) { + match pass.context.compute_pass_set_push_constants( + encoder, + offset, + make_slice(data, size_bytes as usize), + ) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4323,9 +4384,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderMultiDrawIndirect( ) { let pass = pass.as_ref().expect("invalid render pass"); let buffer_id = buffer.as_ref().expect("invalid buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.multi_draw_indirect(&pass.context, buffer_id, offset, count) { + match pass + .context + .render_pass_multi_draw_indirect(encoder, buffer_id, offset, count) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4345,9 +4409,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderMultiDrawIndexedIndirect( ) { let pass = pass.as_ref().expect("invalid render pass"); let buffer_id = buffer.as_ref().expect("invalid buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.multi_draw_indexed_indirect(&pass.context, buffer_id, offset, count) { + match pass + .context + .render_pass_multi_draw_indexed_indirect(encoder, buffer_id, offset, count) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4370,10 +4437,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderMultiDrawIndirectCount( let pass = pass.as_ref().expect("invalid render pass"); let buffer_id = buffer.as_ref().expect("invalid buffer").id; let count_buffer_id = count_buffer.as_ref().expect("invalid count buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.multi_draw_indirect_count( - &pass.context, + match pass.context.render_pass_multi_draw_indirect_count( + encoder, buffer_id, offset, count_buffer_id, @@ -4402,10 +4469,10 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderMultiDrawIndexedIndirectCount( let pass = pass.as_ref().expect("invalid render pass"); let buffer_id = buffer.as_ref().expect("invalid buffer").id; let count_buffer_id = count_buffer.as_ref().expect("invalid count buffer").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.multi_draw_indexed_indirect_count( - &pass.context, + match pass.context.render_pass_multi_draw_indexed_indirect_count( + encoder, buffer_id, offset, count_buffer_id, @@ -4430,9 +4497,13 @@ pub unsafe extern "C" fn wgpuComputePassEncoderBeginPipelineStatisticsQuery( ) { let pass = pass.as_ref().expect("invalid compute pass"); let query_set_id = query_set.as_ref().expect("invalid query set").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.begin_pipeline_statistics_query(&pass.context, query_set_id, query_index) { + match pass.context.compute_pass_begin_pipeline_statistics_query( + encoder, + query_set_id, + query_index, + ) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4448,9 +4519,12 @@ pub unsafe extern "C" fn wgpuComputePassEncoderEndPipelineStatisticsQuery( pass: native::WGPUComputePassEncoder, ) { let pass = pass.as_ref().expect("invalid compute pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.end_pipeline_statistics_query(&pass.context) { + match pass + .context + .compute_pass_end_pipeline_statistics_query(encoder) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4469,9 +4543,13 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderBeginPipelineStatisticsQuery( ) { let pass = pass.as_ref().expect("invalid render pass"); let query_set_id = query_set.as_ref().expect("invalid query set").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.begin_pipeline_statistics_query(&pass.context, query_set_id, query_index) { + match pass.context.render_pass_begin_pipeline_statistics_query( + encoder, + query_set_id, + query_index, + ) { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4487,9 +4565,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderEndPipelineStatisticsQuery( pass: native::WGPURenderPassEncoder, ) { let pass = pass.as_ref().expect("invalid render pass"); - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.end_pipeline_statistics_query(&pass.context) { + match pass + .context + .render_pass_end_pipeline_statistics_query(encoder) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4508,9 +4589,12 @@ pub unsafe extern "C" fn wgpuComputePassEncoderWriteTimestamp( ) { let pass = pass.as_ref().expect("invalid compute pass"); let query_set_id = query_set.as_ref().expect("invalid query set").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.write_timestamp(&pass.context, query_set_id, query_index) { + match pass + .context + .compute_pass_write_timestamp(encoder, query_set_id, query_index) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, @@ -4529,9 +4613,12 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderWriteTimestamp( ) { let pass = pass.as_ref().expect("invalid render pass"); let query_set_id = query_set.as_ref().expect("invalid query set").id; - let encoder = pass.encoder.as_mut().unwrap(); + let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match encoder.write_timestamp(&pass.context, query_set_id, query_index) { + match pass + .context + .render_pass_write_timestamp(encoder, query_set_id, query_index) + { Ok(()) => (), Err(cause) => handle_error( &pass.error_sink, diff --git a/src/logging.rs b/src/logging.rs index f5c31e78..1b71147c 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -1,7 +1,6 @@ -use crate::{map_enum, native}; +use crate::{map_enum, native, utils}; use log::{Level, LevelFilter, Metadata, Record}; use parking_lot::RwLock; -use std::ffi::CString; #[no_mangle] pub extern "C" fn wgpuGetVersion() -> std::os::raw::c_uint { @@ -40,7 +39,6 @@ impl log::Log for Logger { if let Some(callback) = logger.callback { let msg = record.args().to_string(); - let msg_c = CString::new(msg).unwrap(); let level = match record.level() { Level::Error => native::WGPULogLevel_Error, Level::Warn => native::WGPULogLevel_Warn, @@ -50,7 +48,7 @@ impl log::Log for Logger { }; unsafe { - callback(level, msg_c.as_ptr(), logger.userdata); + callback(level, utils::str_into_string_view(&msg), logger.userdata); } // We do not use std::mem::forget(msg_c), so Rust will reclaim the memory diff --git a/src/unimplemented.rs b/src/unimplemented.rs index f58045f8..ab051c79 100644 --- a/src/unimplemented.rs +++ b/src/unimplemented.rs @@ -1,17 +1,14 @@ use crate::native; #[no_mangle] -pub extern "C" fn wgpuGetProcAddress( - _device: native::WGPUDevice, - _proc_name: *const ::std::os::raw::c_char, -) -> native::WGPUProc { +pub extern "C" fn wgpuGetProcAddress(_proc_name: native::WGPUStringView) -> native::WGPUProc { unimplemented!(); } #[no_mangle] pub extern "C" fn wgpuBindGroupSetLabel( _bind_group: native::WGPUBindGroup, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -19,7 +16,7 @@ pub extern "C" fn wgpuBindGroupSetLabel( #[no_mangle] pub extern "C" fn wgpuBindGroupLayoutSetLabel( _bind_group_layout: native::WGPUBindGroupLayout, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -30,17 +27,14 @@ pub extern "C" fn wgpuBufferGetMapState(_buffer: native::WGPUBuffer) -> native:: } #[no_mangle] -pub extern "C" fn wgpuBufferSetLabel( - _buffer: native::WGPUBuffer, - _label: *const ::std::os::raw::c_char, -) { +pub extern "C" fn wgpuBufferSetLabel(_buffer: native::WGPUBuffer, _label: native::WGPUStringView) { unimplemented!(); } #[no_mangle] pub extern "C" fn wgpuCommandBufferSetLabel( _command_buffer: native::WGPUCommandBuffer, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -48,7 +42,7 @@ pub extern "C" fn wgpuCommandBufferSetLabel( #[no_mangle] pub extern "C" fn wgpuCommandEncoderSetLabel( _command_encoder: native::WGPUCommandEncoder, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -56,7 +50,7 @@ pub extern "C" fn wgpuCommandEncoderSetLabel( #[no_mangle] pub extern "C" fn wgpuComputePassEncoderSetLabel( _compute_pass_encoder: native::WGPUComputePassEncoder, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -64,7 +58,7 @@ pub extern "C" fn wgpuComputePassEncoderSetLabel( #[no_mangle] pub extern "C" fn wgpuComputePipelineSetLabel( _compute_pipeline: native::WGPUComputePipeline, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -73,9 +67,8 @@ pub extern "C" fn wgpuComputePipelineSetLabel( pub extern "C" fn wgpuDeviceCreateComputePipelineAsync( _device: native::WGPUDevice, _descriptor: *const native::WGPUComputePipelineDescriptor, - _callback: native::WGPUDeviceCreateComputePipelineAsyncCallback, - _userdata: *mut ::std::os::raw::c_void, -) { + _callback: native::WGPUCreateComputePipelineAsyncCallbackInfo, +) -> native::WGPUFuture { unimplemented!(); } @@ -83,24 +76,38 @@ pub extern "C" fn wgpuDeviceCreateComputePipelineAsync( pub extern "C" fn wgpuDeviceCreateRenderPipelineAsync( _device: native::WGPUDevice, _descriptor: *const native::WGPURenderPipelineDescriptor, - _callback: native::WGPUDeviceCreateRenderPipelineAsyncCallback, - _userdata: *mut ::std::os::raw::c_void, -) { + _callback: native::WGPUCreateRenderPipelineAsyncCallbackInfo, +) -> native::WGPUFuture { unimplemented!(); } #[no_mangle] -pub extern "C" fn wgpuDeviceSetLabel( - _device: native::WGPUDevice, - _label: *const ::std::os::raw::c_char, -) { +pub extern "C" fn wgpuDeviceGetAdapterInfo(_device: native::WGPUDevice) -> native::WGPUAdapterInfo { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn wgpuDeviceGetLostFuture(_device: native::WGPUDevice) -> native::WGPUFuture { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn wgpuDeviceSetLabel(_device: native::WGPUDevice, _label: native::WGPUStringView) { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn wgpuInstanceGetWGSLLanguageFeatures( + _instance: native::WGPUInstance, + _features: *mut native::WGPUSupportedWGSLLanguageFeatures, +) -> native::WGPUStatus { unimplemented!(); } #[no_mangle] pub extern "C" fn wgpuInstanceHasWGSLLanguageFeature( _instance: native::WGPUInstance, - _feature: native::WGPUWGSLFeatureName, + _feature: native::WGPUWGSLLanguageFeatureName, ) -> bool { unimplemented!(); } @@ -113,7 +120,7 @@ pub extern "C" fn wgpuInstanceProcessEvents(_instance: native::WGPUInstance) { #[no_mangle] pub extern "C" fn wgpuPipelineLayoutSetLabel( _pipeline_layout: native::WGPUPipelineLayout, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -121,23 +128,20 @@ pub extern "C" fn wgpuPipelineLayoutSetLabel( #[no_mangle] pub extern "C" fn wgpuQuerySetSetLabel( _query_set: native::WGPUQuerySet, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } #[no_mangle] -pub extern "C" fn wgpuQueueSetLabel( - _queue: native::WGPUQueue, - _label: *const ::std::os::raw::c_char, -) { +pub extern "C" fn wgpuQueueSetLabel(_queue: native::WGPUQueue, _label: native::WGPUStringView) { unimplemented!(); } #[no_mangle] pub extern "C" fn wgpuRenderBundleSetLabel( _render_bundle: native::WGPURenderBundle, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -145,7 +149,7 @@ pub extern "C" fn wgpuRenderBundleSetLabel( #[no_mangle] pub extern "C" fn wgpuRenderBundleEncoderSetLabel( _render_bundle_encoder: native::WGPURenderBundleEncoder, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -153,7 +157,7 @@ pub extern "C" fn wgpuRenderBundleEncoderSetLabel( #[no_mangle] pub extern "C" fn wgpuRenderPassEncoderSetLabel( _render_pass_encoder: native::WGPURenderPassEncoder, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -161,7 +165,7 @@ pub extern "C" fn wgpuRenderPassEncoderSetLabel( #[no_mangle] pub extern "C" fn wgpuRenderPipelineSetLabel( _render_pipeline: native::WGPURenderPipeline, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -169,7 +173,7 @@ pub extern "C" fn wgpuRenderPipelineSetLabel( #[no_mangle] pub extern "C" fn wgpuSamplerSetLabel( _sampler: native::WGPUSampler, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -177,16 +181,22 @@ pub extern "C" fn wgpuSamplerSetLabel( #[no_mangle] pub extern "C" fn wgpuShaderModuleGetCompilationInfo( _shader_module: native::WGPUShaderModule, - _callback: native::WGPUShaderModuleGetCompilationInfoCallback, - _userdata: *mut ::std::os::raw::c_void, -) { + _callback: native::WGPUCompilationInfoCallbackInfo, +) -> native::WGPUFuture { unimplemented!(); } #[no_mangle] pub extern "C" fn wgpuShaderModuleSetLabel( _shader_module: native::WGPUShaderModule, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, +) { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn wgpuSupportedWGSLLanguageFeaturesFreeMembers( + _supported_wgsl_language_features: native::WGPUSupportedWGSLLanguageFeatures, ) { unimplemented!(); } @@ -194,7 +204,7 @@ pub extern "C" fn wgpuShaderModuleSetLabel( #[no_mangle] pub extern "C" fn wgpuSurfaceSetLabel( _surface: native::WGPUSurface, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -202,7 +212,7 @@ pub extern "C" fn wgpuSurfaceSetLabel( #[no_mangle] pub extern "C" fn wgpuTextureSetLabel( _texture: native::WGPUTexture, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } @@ -210,7 +220,17 @@ pub extern "C" fn wgpuTextureSetLabel( #[no_mangle] pub extern "C" fn wgpuTextureViewSetLabel( _texture_view: native::WGPUTextureView, - _label: *const ::std::os::raw::c_char, + _label: native::WGPUStringView, ) { unimplemented!(); } + +#[no_mangle] +pub extern "C" fn wgpuInstanceWaitAny( + _instance: native::WGPUInstance, + _future_count: usize, + _futures: *mut native::WGPUFutureWaitInfo, + _timeout_ns: u64, +) -> native::WGPUWaitStatus { + unimplemented!(); +} diff --git a/src/utils.rs b/src/utils.rs index 8b65f115..0793b39e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,48 +1,42 @@ -use std::{ - borrow::Cow, - ffi::CStr, - path::{Path, PathBuf}, -}; +use std::{borrow::Cow, ffi::CStr}; + +use crate::native; // A dummy wrapper that is `Send` + `Sync` to store userdata pointer // to be usable across Rust callbacks. -pub(crate) struct Userdata(*mut std::ffi::c_void); +pub(crate) struct Userdata(*mut std::ffi::c_void, *mut std::ffi::c_void); impl Userdata { + pub(crate) const NULL: Userdata = Userdata::new(std::ptr::null_mut(), std::ptr::null_mut()); + #[inline] - pub(crate) const fn new(userdata: *mut std::ffi::c_void) -> Userdata { - Userdata(userdata) + pub(crate) const fn new( + userdata1: *mut std::ffi::c_void, + userdata2: *mut std::ffi::c_void, + ) -> Userdata { + Userdata(userdata1, userdata2) } #[inline] - pub(crate) fn as_ptr(&self) -> *mut std::ffi::c_void { + pub(crate) fn get_1(&self) -> *mut std::ffi::c_void { self.0 } -} -unsafe impl Send for Userdata {} -unsafe impl Sync for Userdata {} -#[inline] -pub(crate) fn ptr_into_label<'a>(ptr: *const std::ffi::c_char) -> wgc::Label<'a> { - unsafe { ptr.as_ref() }.and_then(|ptr| { - unsafe { CStr::from_ptr(ptr) } - .to_str() - .ok() - .map(Cow::Borrowed) - }) -} -#[inline] -pub(crate) fn ptr_into_path<'a>(ptr: *const std::ffi::c_char) -> Option<&'a std::path::Path> { - unsafe { ptr.as_ref() } - .and_then(|v| unsafe { CStr::from_ptr(v) }.to_str().ok()) - .map(Path::new) + #[inline] + pub(crate) fn get_2(&self) -> *mut std::ffi::c_void { + self.1 + } } -#[inline] -pub(crate) fn ptr_into_pathbuf(ptr: *const std::ffi::c_char) -> Option { - unsafe { ptr.as_ref() } - .and_then(|v| unsafe { CStr::from_ptr(v) }.to_str().ok()) - .map(PathBuf::from) + +#[macro_export] +macro_rules! new_userdata { + ($var:expr) => { + crate::utils::Userdata::new($var.userdata1, $var.userdata2) + }; } +unsafe impl Send for Userdata {} +unsafe impl Sync for Userdata {} + // Safer wrapper around `slice::from_raw_parts` to handle // invalid `ptr` when `len` is zero. #[inline] @@ -98,6 +92,14 @@ pub fn get_base_device_limits_from_adapter_limits(adapter_limits: &wgt::Limits) } } +pub fn texture_format_has_depth(format: wgt::TextureFormat) -> bool { + return format == wgt::TextureFormat::Depth16Unorm + || format == wgt::TextureFormat::Depth24Plus + || format == wgt::TextureFormat::Depth24PlusStencil8 + || format == wgt::TextureFormat::Depth32Float + || format == wgt::TextureFormat::Depth32FloatStencil8; +} + /// Follow a chain of next pointers and automatically resolve them to the underlying structs. /// /// # Syntax: @@ -164,7 +166,7 @@ macro_rules! follow_chain { $( let mut $stype: Option<&$ty> = None; )* - let mut chain_opt: Option<&$crate::native::WGPUChainedStruct> = $base1.nextInChain.as_ref(); + let mut chain_opt: Option<&$crate::native::WGPUChainedStruct> = ($base1.nextInChain as *const $crate::native::WGPUChainedStruct).as_ref(); while let Some(next_in_chain) = chain_opt { match next_in_chain.sType { $( @@ -268,6 +270,110 @@ macro_rules! map_enum { }; } +/// Equivalent to [map_enum], but it returns [Option] and "undefined" values are converted to [None]. +#[macro_export] +macro_rules! map_enum_with_undefined { + ($name:ident, $c_name:ident, $rs_type:ty, $($variant:ident),+) => { + #[inline] + pub fn $name(value: native::$c_name) -> Result, native::$c_name> { + match value { + paste::paste!(native::[<$c_name _ Undefined>]) => Ok(None), + $(paste::paste!(native::[<$c_name _ $variant>]) => Ok(Some(<$rs_type>::$variant))),+, + x => Err(x), + } + } + }; + ($name:ident, $c_name:ident, $rs_type:ty, $err_msg:literal, $($variant:ident),+) => { + #[inline] + pub fn $name(value: native::$c_name) -> Option<$rs_type> { + map_enum_with_undefined!(map_fn, $c_name, $rs_type, $($variant),+); + + map_fn(value).expect($err_msg) + } + }; + ($name:ident, $c_name:ident, $rs_type:ty, $($native_variant:ident:$variant2:ident),+) => { + #[inline] + pub fn $name(value: native::$c_name) -> Result, native::$c_name> { + match value { + paste::paste!(native::[<$c_name _ Undefined>]) => Ok(None), + $(paste::paste!(native::[<$c_name _ $native_variant>]) => Ok(Some(<$rs_type>::$variant2))),+, + x => Err(x), + } + } + }; + ($name:ident, $c_name:ident, $rs_type:ty, $err_msg:literal, $($native_variant:ident:$variant2:ident),+) => { + #[inline] + pub fn $name(value: native::$c_name) -> Option<$rs_type> { + map_enum_with_undefined!(map_fn, $c_name, $rs_type, $($native_variant:$variant2),+); + + map_fn(value).expect($err_msg) + } + }; +} + +pub unsafe fn string_view_into_str<'a>(string_view: native::WGPUStringView) -> Option<&'a str> { + if string_view.data.is_null() { + match string_view.length { + crate::conv::WGPU_STRLEN => None, + 0 => Some(""), + _ => panic!("Null address to WGPUStringView!"), + } + } else { + let bytes = match string_view.length { + crate::conv::WGPU_STRLEN => CStr::from_ptr(string_view.data).to_bytes(), + _ => make_slice(string_view.data as *const u8, string_view.length), + }; + + Some(std::str::from_utf8_unchecked(bytes)) + } +} + +pub unsafe fn string_view_into_label<'a>(string_view: native::WGPUStringView) -> wgc::Label<'a> { + string_view_into_str(string_view).map(Cow::Borrowed) +} + +pub const fn str_into_string_view(str: &str) -> native::WGPUStringView { + native::WGPUStringView { + data: str.as_ptr() as *const std::os::raw::c_char, + length: str.len(), + } +} + +/// Create a string view that "owns" its memory, so it can be later dropped with [drop_string_view]. +pub fn str_into_owned_string_view(str: &str) -> native::WGPUStringView { + let boxed = String::from(str).into_boxed_str(); + + let result = native::WGPUStringView { + data: boxed.as_ptr() as *const std::os::raw::c_char, + length: boxed.len(), + }; + + std::mem::forget(boxed); + + result +} + +/// Drop a string view created by [str_into_owned_string_view]. +pub unsafe fn drop_string_view(view: native::WGPUStringView) { + if view.data.is_null() { + return; + } + + drop(Box::from_raw(std::slice::from_raw_parts_mut( + view.data as *mut u8, + view.length, + ))) +} + +#[test] +pub fn test_string_view_into_str() { + let str = "Hello, world!"; + let string_view = str_into_string_view(str); + let str_2 = unsafe { string_view_into_str(string_view) }.unwrap(); + + assert_eq!(str, str_2) +} + #[test] pub fn test_get_base_device_limits_from_adapter_limits() { fn expected_limits_with_default_resolution(