From 2e086421b253259016c030421c08446c2394adfc Mon Sep 17 00:00:00 2001 From: Benjamin Hansen Date: Mon, 23 Mar 2026 23:26:24 -0600 Subject: [PATCH 1/2] update code to 29.0 and started news/29.0/readme.md --- Cargo.lock | 320 ++++++++++-------- Cargo.toml | 2 +- code/beginner/tutorial1-window/Cargo.toml | 4 +- code/beginner/tutorial2-surface/Cargo.toml | 4 +- .../tutorial2-surface/src/challenge.rs | 41 ++- code/beginner/tutorial2-surface/src/lib.rs | 41 ++- code/beginner/tutorial3-pipeline/Cargo.toml | 4 +- .../tutorial3-pipeline/src/challenge.rs | 41 ++- code/beginner/tutorial3-pipeline/src/lib.rs | 41 ++- code/beginner/tutorial4-buffer/Cargo.toml | 4 +- .../tutorial4-buffer/src/challenge.rs | 41 ++- code/beginner/tutorial4-buffer/src/lib.rs | 41 ++- code/beginner/tutorial5-textures/Cargo.toml | 4 +- .../tutorial5-textures/src/challenge.rs | 43 ++- code/beginner/tutorial5-textures/src/lib.rs | 43 ++- code/beginner/tutorial6-uniforms/Cargo.toml | 4 +- .../tutorial6-uniforms/src/challenge.rs | 46 ++- code/beginner/tutorial6-uniforms/src/lib.rs | 46 ++- code/beginner/tutorial7-instancing/Cargo.toml | 4 +- .../tutorial7-instancing/src/challenge.rs | 46 ++- code/beginner/tutorial7-instancing/src/lib.rs | 46 ++- code/beginner/tutorial8-depth/Cargo.toml | 4 +- .../beginner/tutorial8-depth/src/challenge.rs | 52 ++- code/beginner/tutorial8-depth/src/lib.rs | 50 ++- code/beginner/tutorial9-models/Cargo.toml | 4 +- code/beginner/tutorial9-models/src/lib.rs | 50 ++- code/compute/Cargo.toml | 4 +- code/compute/src/filter.rs | 2 +- code/compute/src/sort.rs | 2 +- .../tutorial10-lighting/Cargo.toml | 4 +- .../tutorial10-lighting/src/lib.rs | 56 ++- .../tutorial11-normals/Cargo.toml | 4 +- .../tutorial11-normals/src/lib.rs | 56 ++- .../intermediate/tutorial12-camera/Cargo.toml | 4 +- .../intermediate/tutorial12-camera/src/lib.rs | 56 ++- code/intermediate/tutorial13-hdr/Cargo.toml | 2 +- code/intermediate/tutorial13-hdr/src/hdr.rs | 2 +- code/intermediate/tutorial13-hdr/src/lib.rs | 64 ++-- .../tutorial13-hdr/src/resources.rs | 2 +- code/intermediate/wip-terrain/Cargo.toml | 4 +- code/intermediate/wip-terrain/src/lib.rs | 56 ++- code/intermediate/wip-terrain/src/terrain.rs | 8 +- code/showcase/compute/Cargo.toml | 4 +- code/showcase/compute/src/main.rs | 52 ++- code/showcase/compute/src/model.rs | 2 +- code/showcase/compute/src/pipeline.rs | 6 +- code/showcase/framework/Cargo.toml | 2 +- code/showcase/framework/src/lib.rs | 7 +- code/showcase/framework/src/pipeline.rs | 4 +- code/showcase/framework/src/shader_canvas.rs | 2 +- code/showcase/gifs/Cargo.toml | 2 +- code/showcase/gifs/src/main.rs | 5 +- code/showcase/imgui-demo/Cargo.toml | 4 +- code/showcase/mipmaps/src/main.rs | 20 +- code/showcase/mipmaps/src/mipmapper.rs | 2 +- code/showcase/mouse-picking/Cargo.toml | 4 +- code/showcase/offscreen/Cargo.toml | 2 +- code/showcase/pong/Cargo.toml | 6 +- code/showcase/pong/src/render/mod.rs | 7 +- code/showcase/snow/src/main.rs | 22 +- code/showcase/stencil/src/main.rs | 34 +- code/showcase/threading/Cargo.toml | 4 +- code/showcase/threading/src/lib.rs | 56 ++- code/showcase/windowless/Cargo.toml | 2 +- code/showcase/windowless/src/main.rs | 5 +- docs/beginner/tutorial2-surface/README.md | 41 ++- docs/beginner/tutorial5-textures/README.md | 2 +- docs/beginner/tutorial6-uniforms/README.md | 4 +- docs/beginner/tutorial8-depth/README.md | 4 +- .../tutorial10-lighting/README.md | 14 +- docs/intermediate/tutorial13-hdr/readme.md | 10 +- docs/news/29.0/readme.md | 33 ++ docs/news/pre-0.12/readme.md | 46 ++- docs/showcase/mipmaps/readme.md | 2 +- docs/showcase/stencil/readme.md | 10 +- 75 files changed, 1230 insertions(+), 542 deletions(-) create mode 100644 docs/news/29.0/readme.md diff --git a/Cargo.lock b/Cargo.lock index 6cd188bdf..1252a078e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,18 +356,18 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bit-set" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" [[package]] name = "bit_field" @@ -388,18 +388,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] -name = "block" -version = "0.1.6" +name = "block2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] [[package]] name = "block2" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2", + "objc2 0.6.4", ] [[package]] @@ -551,9 +554,9 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", @@ -686,7 +689,7 @@ checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "core-graphics-types 0.1.3", + "core-graphics-types", "foreign-types 0.5.0", "libc", ] @@ -702,17 +705,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", - "libc", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -812,6 +804,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.4", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1328,9 +1330,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" dependencies = [ "js-sys", "slotmap", @@ -2087,15 +2089,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "memchr" version = "2.7.6" @@ -2111,21 +2104,6 @@ dependencies = [ "libc", ] -[[package]] -name = "metal" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" -dependencies = [ - "bitflags 2.10.0", - "block", - "core-graphics-types 0.2.0", - "foreign-types 0.5.0", - "log 0.4.29", - "objc", - "paste", -] - [[package]] name = "mime" version = "0.3.17" @@ -2169,9 +2147,9 @@ dependencies = [ [[package]] name = "naga" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" +checksum = "85b4372fed0bd362d646d01b6926df0e837859ccc522fed720c395e0460f29c8" dependencies = [ "arrayvec", "bit-set", @@ -2293,15 +2271,6 @@ dependencies = [ "syn", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -2318,6 +2287,15 @@ dependencies = [ "objc2-encode", ] +[[package]] +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-app-kit" version = "0.2.2" @@ -2325,13 +2303,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "libc", - "objc2", + "objc2 0.5.2", "objc2-core-data", "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -2341,10 +2319,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2353,9 +2331,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2365,9 +2343,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.10.0", + "dispatch2", + "objc2 0.6.4", ] [[package]] @@ -2376,10 +2365,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", - "objc2", - "objc2-foundation", - "objc2-metal", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", ] [[package]] @@ -2388,10 +2377,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-contacts", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2407,10 +2396,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "dispatch", "libc", - "objc2", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.4", + "objc2-core-foundation", ] [[package]] @@ -2419,10 +2419,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2432,9 +2432,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-foundation 0.3.2", ] [[package]] @@ -2444,10 +2456,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", - "objc2-foundation", - "objc2-metal", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", ] [[package]] @@ -2456,8 +2481,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" dependencies = [ - "objc2", - "objc2-foundation", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2467,15 +2492,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", "objc2-core-image", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", @@ -2487,9 +2512,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", - "objc2", - "objc2-foundation", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", ] [[package]] @@ -2499,10 +2524,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.10.0", - "block2", - "objc2", + "block2 0.5.1", + "objc2 0.5.2", "objc2-core-location", - "objc2-foundation", + "objc2-foundation 0.2.2", ] [[package]] @@ -2660,12 +2685,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "percent-encoding" version = "2.3.2" @@ -3009,6 +3028,18 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + [[package]] name = "rayon" version = "1.11.0" @@ -3610,9 +3641,9 @@ dependencies = [ [[package]] name = "spirv" -version = "0.3.0+sdk-1.3.268.0" +version = "0.4.0+sdk-1.4.341.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" dependencies = [ "bitflags 2.10.0", ] @@ -4723,9 +4754,9 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" +checksum = "78f9f386699b1fb8b8a05bfe82169b24d151f05702d2905a0bf93bc454fcc825" dependencies = [ "arrayvec", "bitflags 2.10.0", @@ -4753,9 +4784,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb4c8b5db5f00e56f1f08869d870a0dff7c8bc7ebc01091fec140b0cf0211a9" +checksum = "c7c34181b0acb8f98168f78f8e57ec66f57df5522b39143dbe5f2f45d7ca927c" dependencies = [ "arrayvec", "bit-set", @@ -4781,61 +4812,61 @@ dependencies = [ "wgpu-core-deps-wasm", "wgpu-core-deps-windows-linux-android", "wgpu-hal", + "wgpu-naga-bridge", "wgpu-types", ] [[package]] name = "wgpu-core-deps-apple" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da" +checksum = "43acd053312501689cd92a01a9638d37f3e41a5fd9534875efa8917ee2d11ac0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79" +checksum = "ef043bf135cc68b6f667c55ff4e345ce2b5924d75bad36a47921b0287ca4b24a" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a2cf578ce8d7d50d0e63ddc2345c7dcb599f6eb90b888813406ea78b9b7010" +checksum = "2f7b75e72f49035f000dd5262e4126242e92a090a4fd75931ecfe7e60784e6fa" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae" +checksum = "725d5c006a8c02967b6d93ef04f6537ec4593313e330cfe86d9d3f946eb90f28" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293080d77fdd14d6b08a67c5487dfddbf874534bb7921526db56a7b75d7e3bef" +checksum = "058b6047337cf323a4f092486443a9337f3d81325347e5d77deed7e563aeaedc" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", "bitflags 2.10.0", - "block", + "block2 0.6.2", "bytemuck", "cfg-if", "cfg_aliases", - "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", "gpu-allocator", @@ -4846,10 +4877,13 @@ dependencies = [ "libc", "libloading", "log 0.4.29", - "metal", "naga", "ndk-sys", - "objc", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", "once_cell", "ordered-float", "parking_lot 0.12.5", @@ -4858,26 +4892,40 @@ dependencies = [ "profiling", "range-alloc", "raw-window-handle", + "raw-window-metal", "renderdoc-sys", "smallvec", "thiserror 2.0.17", "wasm-bindgen", + "wayland-sys", "web-sys", + "wgpu-naga-bridge", "wgpu-types", "windows", "windows-core", ] +[[package]] +name = "wgpu-naga-bridge" +version = "29.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0b8e1e505095f24cb4a578f04b1421d456257dca7fac114d9d9dd3d978c34b8" +dependencies = [ + "naga", + "wgpu-types", +] + [[package]] name = "wgpu-types" -version = "28.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" +checksum = "d15ece45db77dd5451f11c0ce898334317ce8502d304a20454b531fdc0652fae" dependencies = [ "bitflags 2.10.0", "bytemuck", "js-sys", "log 0.4.29", + "raw-window-handle", "web-sys", ] @@ -5350,7 +5398,7 @@ dependencies = [ "android-activity", "atomic-waker", "bitflags 2.10.0", - "block2", + "block2 0.5.1", "bytemuck", "calloop", "cfg_aliases", @@ -5363,9 +5411,9 @@ dependencies = [ "libc", "memmap2", "ndk", - "objc2", + "objc2 0.5.2", "objc2-app-kit", - "objc2-foundation", + "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", "percent-encoding", diff --git a/Cargo.toml b/Cargo.toml index 31eabbd51..6ddf43798 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ exclude = [ ] [workspace.dependencies] -wgpu = "28.0" +wgpu = "29.0" anyhow = "1" glam = { version = "0.30.9", features = ["bytemuck"] } bytemuck = { version = "1.13.1", features = ["derive"] } diff --git a/code/beginner/tutorial1-window/Cargo.toml b/code/beginner/tutorial1-window/Cargo.toml index 8bb37c603..b4e685c6e 100644 --- a/code/beginner/tutorial1-window/Cargo.toml +++ b/code/beginner/tutorial1-window/Cargo.toml @@ -16,13 +16,13 @@ anyhow = "1.0" winit = { version = "0.30" } env_logger = "0.10" log = "0.4" -wgpu = "28.0" +wgpu = "29.0" pollster = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4.30" web-sys = { version = "0.3.69", features = [ diff --git a/code/beginner/tutorial2-surface/Cargo.toml b/code/beginner/tutorial2-surface/Cargo.toml index d151ff55f..ca7ac127d 100644 --- a/code/beginner/tutorial2-surface/Cargo.toml +++ b/code/beginner/tutorial2-surface/Cargo.toml @@ -12,13 +12,13 @@ anyhow = "1.0" winit = { version = "0.30", features = ["android-native-activity"] } env_logger = "0.10" log = "0.4" -wgpu = "28.0" +wgpu = "29.0" pollster = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial2-surface/src/challenge.rs b/code/beginner/tutorial2-surface/src/challenge.rs index ed58d337a..69b6bf42c 100644 --- a/code/beginner/tutorial2-surface/src/challenge.rs +++ b/code/beginner/tutorial2-surface/src/challenge.rs @@ -28,12 +28,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -111,10 +114,31 @@ impl State { #[allow(unused)] fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -255,13 +279,10 @@ impl ApplicationHandler for App { WindowEvent::RedrawRequested => { match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial2-surface/src/lib.rs b/code/beginner/tutorial2-surface/src/lib.rs index 1000a45a8..ebaafc530 100644 --- a/code/beginner/tutorial2-surface/src/lib.rs +++ b/code/beginner/tutorial2-surface/src/lib.rs @@ -28,12 +28,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -106,7 +109,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -114,7 +117,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -256,13 +280,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial3-pipeline/Cargo.toml b/code/beginner/tutorial3-pipeline/Cargo.toml index 80595f35f..26c827886 100644 --- a/code/beginner/tutorial3-pipeline/Cargo.toml +++ b/code/beginner/tutorial3-pipeline/Cargo.toml @@ -12,13 +12,13 @@ anyhow = "1.0" winit = { version = "0.30", features = ["android-native-activity"] } env_logger = "0.10" log = "0.4" -wgpu = "28.0" +wgpu = "29.0" pollster = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial3-pipeline/src/challenge.rs b/code/beginner/tutorial3-pipeline/src/challenge.rs index 81fba41ff..d739579f9 100644 --- a/code/beginner/tutorial3-pipeline/src/challenge.rs +++ b/code/beginner/tutorial3-pipeline/src/challenge.rs @@ -31,12 +31,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -232,7 +235,7 @@ impl State { #[allow(dead_code)] fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -240,7 +243,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -385,13 +409,10 @@ impl ApplicationHandler for App { WindowEvent::RedrawRequested => { match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial3-pipeline/src/lib.rs b/code/beginner/tutorial3-pipeline/src/lib.rs index 29ed9058e..55757d065 100644 --- a/code/beginner/tutorial3-pipeline/src/lib.rs +++ b/code/beginner/tutorial3-pipeline/src/lib.rs @@ -30,12 +30,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -177,7 +180,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -185,7 +188,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -323,13 +347,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial4-buffer/Cargo.toml b/code/beginner/tutorial4-buffer/Cargo.toml index 5eeee6a59..144efcd45 100644 --- a/code/beginner/tutorial4-buffer/Cargo.toml +++ b/code/beginner/tutorial4-buffer/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] anyhow = "1.0" winit = { version = "0.30", features = ["android-native-activity"] } -wgpu = "28.0" +wgpu = "29.0" env_logger = "0.10" log = "0.4" pollster = "0.3" @@ -21,7 +21,7 @@ bytemuck = { version = "1.24", features = [ "derive" ] } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial4-buffer/src/challenge.rs b/code/beginner/tutorial4-buffer/src/challenge.rs index 9d3c5b255..5d6d383e2 100644 --- a/code/beginner/tutorial4-buffer/src/challenge.rs +++ b/code/beginner/tutorial4-buffer/src/challenge.rs @@ -94,12 +94,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); // # Safety @@ -296,7 +299,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -304,7 +307,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -459,13 +483,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial4-buffer/src/lib.rs b/code/beginner/tutorial4-buffer/src/lib.rs index 8a7ab99f2..7fbc22f13 100644 --- a/code/beginner/tutorial4-buffer/src/lib.rs +++ b/code/beginner/tutorial4-buffer/src/lib.rs @@ -87,12 +87,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); // # Safety @@ -251,7 +254,7 @@ impl State { } } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -259,7 +262,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -399,13 +423,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial5-textures/Cargo.toml b/code/beginner/tutorial5-textures/Cargo.toml index 2405a0bf6..430f875d0 100644 --- a/code/beginner/tutorial5-textures/Cargo.toml +++ b/code/beginner/tutorial5-textures/Cargo.toml @@ -13,7 +13,7 @@ bytemuck = { version = "1.24", features = [ "derive" ] } env_logger = "0.10" log = "0.4" pollster = "0.3" -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -24,7 +24,7 @@ features = ["png", "jpeg"] [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial5-textures/src/challenge.rs b/code/beginner/tutorial5-textures/src/challenge.rs index 8080aa560..2a5204d16 100644 --- a/code/beginner/tutorial5-textures/src/challenge.rs +++ b/code/beginner/tutorial5-textures/src/challenge.rs @@ -96,12 +96,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); // # Safety @@ -227,7 +230,7 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout], + bind_group_layouts: &[Some(&texture_bind_group_layout)], immediate_size: 0, }); @@ -329,7 +332,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -337,7 +340,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -488,13 +512,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial5-textures/src/lib.rs b/code/beginner/tutorial5-textures/src/lib.rs index 2915c5fcf..942294554 100644 --- a/code/beginner/tutorial5-textures/src/lib.rs +++ b/code/beginner/tutorial5-textures/src/lib.rs @@ -93,12 +93,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -200,7 +203,7 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout], + bind_group_layouts: &[Some(&texture_bind_group_layout)], immediate_size: 0, }); @@ -298,7 +301,7 @@ impl State { fn update(&mut self) {} - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -306,7 +309,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -447,13 +471,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial6-uniforms/Cargo.toml b/code/beginner/tutorial6-uniforms/Cargo.toml index 6e7957b28..c81c334a3 100644 --- a/code/beginner/tutorial6-uniforms/Cargo.toml +++ b/code/beginner/tutorial6-uniforms/Cargo.toml @@ -14,7 +14,7 @@ cgmath = "0.18" env_logger = "0.10" log = "0.4" pollster = "0.3" -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -25,7 +25,7 @@ features = ["png", "jpeg"] [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial6-uniforms/src/challenge.rs b/code/beginner/tutorial6-uniforms/src/challenge.rs index 7fb1b9a10..27ff61d9c 100644 --- a/code/beginner/tutorial6-uniforms/src/challenge.rs +++ b/code/beginner/tutorial6-uniforms/src/challenge.rs @@ -232,12 +232,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -384,7 +387,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -501,7 +507,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -509,7 +515,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -655,13 +682,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial6-uniforms/src/lib.rs b/code/beginner/tutorial6-uniforms/src/lib.rs index 0a2e7b1ae..caae78983 100644 --- a/code/beginner/tutorial6-uniforms/src/lib.rs +++ b/code/beginner/tutorial6-uniforms/src/lib.rs @@ -229,12 +229,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -380,7 +383,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -499,7 +505,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -507,7 +513,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -649,13 +676,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial7-instancing/Cargo.toml b/code/beginner/tutorial7-instancing/Cargo.toml index a24ce480e..9609e2407 100644 --- a/code/beginner/tutorial7-instancing/Cargo.toml +++ b/code/beginner/tutorial7-instancing/Cargo.toml @@ -14,7 +14,7 @@ cgmath = "0.18" env_logger = "0.10" log = "0.4" pollster = "0.3" -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -25,7 +25,7 @@ features = ["png", "jpeg"] [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial7-instancing/src/challenge.rs b/code/beginner/tutorial7-instancing/src/challenge.rs index a146bf728..2d8c234a7 100644 --- a/code/beginner/tutorial7-instancing/src/challenge.rs +++ b/code/beginner/tutorial7-instancing/src/challenge.rs @@ -286,12 +286,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -469,7 +472,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -605,7 +611,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -613,7 +619,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -760,13 +787,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial7-instancing/src/lib.rs b/code/beginner/tutorial7-instancing/src/lib.rs index aab8a3fc6..78b3a4d46 100644 --- a/code/beginner/tutorial7-instancing/src/lib.rs +++ b/code/beginner/tutorial7-instancing/src/lib.rs @@ -290,12 +290,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -473,7 +476,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -590,7 +596,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -598,7 +604,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -742,13 +769,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial8-depth/Cargo.toml b/code/beginner/tutorial8-depth/Cargo.toml index 46b350b0f..cdf8ba97a 100644 --- a/code/beginner/tutorial8-depth/Cargo.toml +++ b/code/beginner/tutorial8-depth/Cargo.toml @@ -14,7 +14,7 @@ cgmath = "0.18" env_logger = "0.10" pollster = "0.3" log = "0.4" -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -25,7 +25,7 @@ features = ["png", "jpeg"] [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial8-depth/src/challenge.rs b/code/beginner/tutorial8-depth/src/challenge.rs index 2b6a4e26a..2ec73d484 100644 --- a/code/beginner/tutorial8-depth/src/challenge.rs +++ b/code/beginner/tutorial8-depth/src/challenge.rs @@ -345,7 +345,7 @@ impl DepthPass { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Depth Pass Pipeline Layout"), - bind_group_layouts: &[&layout], + bind_group_layouts: &[Some(&layout)], immediate_size: 0, }); @@ -491,12 +491,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -674,7 +677,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -715,8 +721,8 @@ impl State { }, depth_stencil: Some(wgpu::DepthStencilState { format: texture::Texture::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState { constant: 2, // Corresponds to bilinear filtering @@ -809,7 +815,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -817,7 +823,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -973,13 +1000,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial8-depth/src/lib.rs b/code/beginner/tutorial8-depth/src/lib.rs index f2ab2d7f1..57dd8121d 100644 --- a/code/beginner/tutorial8-depth/src/lib.rs +++ b/code/beginner/tutorial8-depth/src/lib.rs @@ -300,12 +300,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -486,7 +489,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -527,8 +533,8 @@ impl State { }, depth_stencil: Some(wgpu::DepthStencilState { format: texture::Texture::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -615,7 +621,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -623,7 +629,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -773,13 +800,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/beginner/tutorial9-models/Cargo.toml b/code/beginner/tutorial9-models/Cargo.toml index c44af1fa7..c3f6586ab 100644 --- a/code/beginner/tutorial9-models/Cargo.toml +++ b/code/beginner/tutorial9-models/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -27,7 +27,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/beginner/tutorial9-models/src/lib.rs b/code/beginner/tutorial9-models/src/lib.rs index c31b792f8..60ae7c236 100644 --- a/code/beginner/tutorial9-models/src/lib.rs +++ b/code/beginner/tutorial9-models/src/lib.rs @@ -241,12 +241,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU log::warn!("WGPU setup"); - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -414,7 +417,10 @@ impl State { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout, &camera_bind_group_layout], + bind_group_layouts: &[ + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + ], immediate_size: 0, }); @@ -455,8 +461,8 @@ impl State { }, depth_stencil: Some(wgpu::DepthStencilState { format: texture::Texture::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -527,7 +533,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -535,7 +541,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -685,13 +712,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/compute/Cargo.toml b/code/compute/Cargo.toml index 4ab228682..6e0f92cdd 100644 --- a/code/compute/Cargo.toml +++ b/code/compute/Cargo.toml @@ -18,7 +18,7 @@ bytemuck = "1.23.2" glam = "0.30.5" log = "0.4.28" pollster = "0.4.0" -wgpu = "28.0" +wgpu = "29.0" env_logger = "0.11.8" crossbeam = "0.8.4" flume = "0.11.1" @@ -26,7 +26,7 @@ flume = "0.11.1" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.6" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4.30" web-sys = { version = "0.3.69", features = [ diff --git a/code/compute/src/filter.rs b/code/compute/src/filter.rs index eea16b1e5..b82a2ebb0 100644 --- a/code/compute/src/filter.rs +++ b/code/compute/src/filter.rs @@ -2,7 +2,7 @@ use flume::bounded; use wgpu::util::{BufferInitDescriptor, DeviceExt}; pub async fn run() -> anyhow::Result<()> { - let instance = wgpu::Instance::new(&Default::default()); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); let adapter = instance.request_adapter(&Default::default()).await.unwrap(); let (device, queue) = adapter.request_device(&Default::default()).await.unwrap(); diff --git a/code/compute/src/sort.rs b/code/compute/src/sort.rs index 87332b5b6..caa5d69fd 100644 --- a/code/compute/src/sort.rs +++ b/code/compute/src/sort.rs @@ -2,7 +2,7 @@ use flume::bounded; use wgpu::util::{BufferInitDescriptor, DeviceExt}; pub async fn run() -> anyhow::Result<()> { - let instance = wgpu::Instance::new(&Default::default()); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); let adapter = instance.request_adapter(&Default::default()).await.unwrap(); let (device, queue) = adapter.request_device(&Default::default()).await.unwrap(); diff --git a/code/intermediate/tutorial10-lighting/Cargo.toml b/code/intermediate/tutorial10-lighting/Cargo.toml index eb277cce6..fbfe4b4a7 100644 --- a/code/intermediate/tutorial10-lighting/Cargo.toml +++ b/code/intermediate/tutorial10-lighting/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -27,7 +27,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/intermediate/tutorial10-lighting/src/lib.rs b/code/intermediate/tutorial10-lighting/src/lib.rs index dd320d2c4..65161515d 100644 --- a/code/intermediate/tutorial10-lighting/src/lib.rs +++ b/code/intermediate/tutorial10-lighting/src/lib.rs @@ -315,8 +315,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -338,12 +338,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -542,9 +545,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -567,7 +570,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -654,7 +660,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -662,7 +668,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -819,13 +846,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/intermediate/tutorial11-normals/Cargo.toml b/code/intermediate/tutorial11-normals/Cargo.toml index 0239d2082..cc27cf0f7 100644 --- a/code/intermediate/tutorial11-normals/Cargo.toml +++ b/code/intermediate/tutorial11-normals/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } [dependencies.image] @@ -27,7 +27,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/intermediate/tutorial11-normals/src/lib.rs b/code/intermediate/tutorial11-normals/src/lib.rs index 6fd0f6570..aa5c2912b 100644 --- a/code/intermediate/tutorial11-normals/src/lib.rs +++ b/code/intermediate/tutorial11-normals/src/lib.rs @@ -315,8 +315,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -338,12 +338,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -559,9 +562,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -586,7 +589,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -701,7 +707,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -709,7 +715,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -866,13 +893,10 @@ impl ApplicationHandler for App { state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/intermediate/tutorial12-camera/Cargo.toml b/code/intermediate/tutorial12-camera/Cargo.toml index 95c910c4e..20723d913 100644 --- a/code/intermediate/tutorial12-camera/Cargo.toml +++ b/code/intermediate/tutorial12-camera/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1" @@ -28,7 +28,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/intermediate/tutorial12-camera/src/lib.rs b/code/intermediate/tutorial12-camera/src/lib.rs index 05ca65531..72cbc503b 100644 --- a/code/intermediate/tutorial12-camera/src/lib.rs +++ b/code/intermediate/tutorial12-camera/src/lib.rs @@ -207,8 +207,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -230,12 +230,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -445,9 +448,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -470,7 +473,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -607,7 +613,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -615,7 +621,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -797,13 +824,10 @@ impl ApplicationHandler for App { state.update(dt); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/intermediate/tutorial13-hdr/Cargo.toml b/code/intermediate/tutorial13-hdr/Cargo.toml index c87e2df28..f9f69057d 100644 --- a/code/intermediate/tutorial13-hdr/Cargo.toml +++ b/code/intermediate/tutorial13-hdr/Cargo.toml @@ -18,7 +18,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1" diff --git a/code/intermediate/tutorial13-hdr/src/hdr.rs b/code/intermediate/tutorial13-hdr/src/hdr.rs index 5c122c749..14f9940f7 100644 --- a/code/intermediate/tutorial13-hdr/src/hdr.rs +++ b/code/intermediate/tutorial13-hdr/src/hdr.rs @@ -72,7 +72,7 @@ impl HdrPipeline { let shader = wgpu::include_wgsl!("hdr.wgsl"); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&layout], + bind_group_layouts: &[Some(&layout)], immediate_size: 0, }); diff --git a/code/intermediate/tutorial13-hdr/src/lib.rs b/code/intermediate/tutorial13-hdr/src/lib.rs index 6edaf28c0..d8bce9736 100644 --- a/code/intermediate/tutorial13-hdr/src/lib.rs +++ b/code/intermediate/tutorial13-hdr/src/lib.rs @@ -228,8 +228,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::LessEqual, // UDPATED! + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::LessEqual), // UDPATED! stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -251,13 +251,16 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { // UPDATED #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::BROWSER_WEBGPU, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -514,10 +517,10 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, - &environment_layout, // UPDATED! + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + Some(&environment_layout), // UPDATED! ], immediate_size: 0, }); @@ -541,7 +544,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -563,7 +569,7 @@ impl State { let sky_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Sky Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &environment_layout], + bind_group_layouts: &[Some(&camera_bind_group_layout), Some(&environment_layout)], immediate_size: 0, }); let shader = wgpu::include_wgsl!("sky.wgsl"); @@ -609,7 +615,7 @@ impl State { }; #[cfg(feature = "debug")] - let debug = debug::Debug::new(&device, &camera_bind_group_layout, surface_format); + let debug = debug::Debug::new(&device, Some(&camera_bind_group_layout), surface_format); Ok(Self { window, @@ -706,7 +712,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -714,7 +720,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output.texture.create_view(&wgpu::TextureViewDescriptor { format: Some(self.config.format.add_srgb_suffix()), ..Default::default() @@ -928,13 +955,10 @@ impl ApplicationHandler for App { state.update(dt); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } @@ -971,7 +995,7 @@ pub fn run() -> anyhow::Result<()> { } let event_loop = EventLoop::with_user_event().build()?; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(target_arch = "wasm32"))] { let mut app = App::new(); event_loop.run_app(&mut app)?; diff --git a/code/intermediate/tutorial13-hdr/src/resources.rs b/code/intermediate/tutorial13-hdr/src/resources.rs index bceda02ac..91478d65d 100644 --- a/code/intermediate/tutorial13-hdr/src/resources.rs +++ b/code/intermediate/tutorial13-hdr/src/resources.rs @@ -251,7 +251,7 @@ impl HdrLoader { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&equirect_layout], + bind_group_layouts: &[Some(&equirect_layout)], immediate_size: 0, }); diff --git a/code/intermediate/wip-terrain/Cargo.toml b/code/intermediate/wip-terrain/Cargo.toml index e2aec7ab2..53574ba66 100644 --- a/code/intermediate/wip-terrain/Cargo.toml +++ b/code/intermediate/wip-terrain/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0" } +wgpu = { version = "29.0" } winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1" @@ -28,7 +28,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/intermediate/wip-terrain/src/lib.rs b/code/intermediate/wip-terrain/src/lib.rs index 7a15ae5a2..e1b8dbd36 100644 --- a/code/intermediate/wip-terrain/src/lib.rs +++ b/code/intermediate/wip-terrain/src/lib.rs @@ -210,8 +210,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -233,12 +233,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -448,9 +451,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -474,7 +477,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let desc = wgpu::ShaderModuleDescriptor { @@ -654,7 +660,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -662,7 +668,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output.texture.create_view(&wgpu::TextureViewDescriptor { format: Some(self.config.format.add_srgb_suffix()), ..Default::default() @@ -853,13 +880,10 @@ impl ApplicationHandler for App { state.update(dt); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/intermediate/wip-terrain/src/terrain.rs b/code/intermediate/wip-terrain/src/terrain.rs index 079791bd6..6400b92a4 100644 --- a/code/intermediate/wip-terrain/src/terrain.rs +++ b/code/intermediate/wip-terrain/src/terrain.rs @@ -121,7 +121,7 @@ impl TerrainPipeline { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("TerrainPipeline::Gen::PipelineLayout"), - bind_group_layouts: &[&gen_layout], + bind_group_layouts: &[Some(&gen_layout)], immediate_size: 0, }); let gen_pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor { @@ -136,7 +136,11 @@ impl TerrainPipeline { let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("TerrainPipeline::Render::PipelineLayout"), - bind_group_layouts: &[camera_layout, light_layout, material_layout], + bind_group_layouts: &[ + Some(camera_layout), + Some(light_layout), + Some(material_layout), + ], immediate_size: 0, }); let render_pipeline = create_render_pipeline( diff --git a/code/showcase/compute/Cargo.toml b/code/showcase/compute/Cargo.toml index 8cac63867..f943c35d4 100644 --- a/code/showcase/compute/Cargo.toml +++ b/code/showcase/compute/Cargo.toml @@ -14,7 +14,7 @@ image = "0.24" log = "0.4" rayon = "1.4" tobj = "2.0" -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1.13" @@ -23,4 +23,4 @@ anyhow = "1.0" fs_extra = "1.2" glob = "0.3" rayon = "1.4" -naga = { version = "28.0", features = ["glsl-in", "spv-out", "wgsl-out"]} +naga = { version = "29.0", features = ["glsl-in", "spv-out", "wgsl-out"]} diff --git a/code/showcase/compute/src/main.rs b/code/showcase/compute/src/main.rs index edf37c54c..d3375ea85 100644 --- a/code/showcase/compute/src/main.rs +++ b/code/showcase/compute/src/main.rs @@ -167,12 +167,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -393,9 +396,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -415,7 +418,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); @@ -524,14 +530,35 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); if !self.is_surface_configured { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture @@ -739,13 +766,10 @@ impl ApplicationHandler for App { state.update(dt); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/showcase/compute/src/model.rs b/code/showcase/compute/src/model.rs index 4dc6cc58f..73ab99a8f 100644 --- a/code/showcase/compute/src/model.rs +++ b/code/showcase/compute/src/model.rs @@ -241,7 +241,7 @@ impl ModelLoader { let shader_src = wgpu::include_wgsl!("model_load.comp.wgsl"); let pipeline = pipeline::create_compute_pipeline( device, - &[&binder.layout], + &[Some(&binder.layout)], shader_src, Some("ModelLoader ComputePipeline"), ); diff --git a/code/showcase/compute/src/pipeline.rs b/code/showcase/compute/src/pipeline.rs index e01fae495..3fb55531a 100644 --- a/code/showcase/compute/src/pipeline.rs +++ b/code/showcase/compute/src/pipeline.rs @@ -79,8 +79,8 @@ pub fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -98,7 +98,7 @@ pub fn create_render_pipeline( pub fn create_compute_pipeline( device: &wgpu::Device, - bind_group_layouts: &[&wgpu::BindGroupLayout], + bind_group_layouts: &[Option<&wgpu::BindGroupLayout>], shader_src: wgpu::ShaderModuleDescriptor, label: Option<&str>, ) -> wgpu::ComputePipeline { diff --git a/code/showcase/framework/Cargo.toml b/code/showcase/framework/Cargo.toml index a06d92134..b00fd9f7d 100644 --- a/code/showcase/framework/Cargo.toml +++ b/code/showcase/framework/Cargo.toml @@ -45,5 +45,5 @@ instant = { version = "0.1", features = [ "wasm-bindgen" ] } anyhow = "1.0" fs_extra = "1.2" glob = "0.3" -naga = { version = "28.0", features = ["glsl-in", "spv-out", "wgsl-out"]} +naga = { version = "29.0", features = ["glsl-in", "spv-out", "wgsl-out"]} rayon = "1.5" diff --git a/code/showcase/framework/src/lib.rs b/code/showcase/framework/src/lib.rs index 4aa327cb4..24cb302c6 100644 --- a/code/showcase/framework/src/lib.rs +++ b/code/showcase/framework/src/lib.rs @@ -50,12 +50,15 @@ pub struct Display { impl Display { pub async fn new(window: Arc) -> anyhow::Result { let size = window.inner_size(); - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); let adapter = instance diff --git a/code/showcase/framework/src/pipeline.rs b/code/showcase/framework/src/pipeline.rs index c594510a9..205f8ff7b 100644 --- a/code/showcase/framework/src/pipeline.rs +++ b/code/showcase/framework/src/pipeline.rs @@ -139,8 +139,8 @@ impl<'a> RenderPipelineBuilder<'a> { ) -> &mut Self { self.depth_stencil(wgpu::DepthStencilState { format, - depth_write_enabled, - depth_compare, + depth_write_enabled: Some(depth_write_enabled), + depth_compare: Some(depth_compare), stencil: Default::default(), bias: wgpu::DepthBiasState::default(), }) diff --git a/code/showcase/framework/src/shader_canvas.rs b/code/showcase/framework/src/shader_canvas.rs index 8549fb582..427939cd5 100644 --- a/code/showcase/framework/src/shader_canvas.rs +++ b/code/showcase/framework/src/shader_canvas.rs @@ -203,7 +203,7 @@ impl<'a> ShaderCanvasBuilder<'a> { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: self.label, - bind_group_layouts: &[&simulation_bind_group_layout], + bind_group_layouts: &[Some(&simulation_bind_group_layout)], immediate_size: 0, }); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { diff --git a/code/showcase/gifs/Cargo.toml b/code/showcase/gifs/Cargo.toml index 108d7338a..3dcc4bae4 100644 --- a/code/showcase/gifs/Cargo.toml +++ b/code/showcase/gifs/Cargo.toml @@ -14,7 +14,7 @@ pollster = "0.3" image = "0.24.2" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30", features = ["android-native-activity"] } gif = "0.11.4" futures-intrusive = "0.4" diff --git a/code/showcase/gifs/src/main.rs b/code/showcase/gifs/src/main.rs index cccda8c05..7bd6def82 100644 --- a/code/showcase/gifs/src/main.rs +++ b/code/showcase/gifs/src/main.rs @@ -5,10 +5,7 @@ use std::{iter, mem}; use pollster::FutureExt; async fn run() { - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { - backends: wgpu::Backends::all(), - ..Default::default() - }); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions::default()) .await diff --git a/code/showcase/imgui-demo/Cargo.toml b/code/showcase/imgui-demo/Cargo.toml index 87442bccf..8d42a7e53 100644 --- a/code/showcase/imgui-demo/Cargo.toml +++ b/code/showcase/imgui-demo/Cargo.toml @@ -8,9 +8,9 @@ edition = "2018" [dependencies] anyhow = "1.0" -wgpu = "28.0" +wgpu = "29.0" pollster = "0.3" imgui = "0.7" -imgui-wgpu = "28.0" +imgui-wgpu = "29.0" imgui-winit-support = "0.7" framework = { path = "../framework" } \ No newline at end of file diff --git a/code/showcase/mipmaps/src/main.rs b/code/showcase/mipmaps/src/main.rs index 0912c9c4c..d8bc590fd 100644 --- a/code/showcase/mipmaps/src/main.rs +++ b/code/showcase/mipmaps/src/main.rs @@ -418,7 +418,7 @@ impl Demo for Mipmaps { .device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&camera_layout, &texture_layout], + bind_group_layouts: &[Some(&camera_layout), Some(&texture_layout)], immediate_size: 0, }); @@ -506,9 +506,21 @@ impl Demo for Mipmaps { fn render(&mut self, display: &mut framework::Display) { let frame = match display.surface().get_current_texture() { - Ok(frame) => frame, - Err(wgpu::SurfaceError::Outdated) => return, - Err(e) => panic!("{}", e), + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + display.configure(); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => return, + wgpu::CurrentSurfaceTexture::Outdated => { + display.configure(); + return; + } + wgpu::CurrentSurfaceTexture::Lost => { + panic!("Context lost"); + } }; let view = frame.texture.create_view(&Default::default()); diff --git a/code/showcase/mipmaps/src/mipmapper.rs b/code/showcase/mipmaps/src/mipmapper.rs index 48697b714..49083d9f2 100644 --- a/code/showcase/mipmaps/src/mipmapper.rs +++ b/code/showcase/mipmaps/src/mipmapper.rs @@ -40,7 +40,7 @@ impl Mipmapper { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&storage_texture_layout], + bind_group_layouts: &[Some(&storage_texture_layout)], immediate_size: 0, }); let compute_module = device.create_shader_module(wgpu::include_wgsl!("mipmap.wgsl")); diff --git a/code/showcase/mouse-picking/Cargo.toml b/code/showcase/mouse-picking/Cargo.toml index 90ecf9d8b..780992fb6 100644 --- a/code/showcase/mouse-picking/Cargo.toml +++ b/code/showcase/mouse-picking/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10" pollster = "0.3" log = "0.4" tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1" framework = { version = "0.1.0", path = "../framework" } @@ -29,7 +29,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/showcase/offscreen/Cargo.toml b/code/showcase/offscreen/Cargo.toml index 6d07835bd..5d7f456ac 100644 --- a/code/showcase/offscreen/Cargo.toml +++ b/code/showcase/offscreen/Cargo.toml @@ -23,5 +23,5 @@ web-sys = { version = "0.3", features = [ "Url", "DedicatedWorkerGlobalScope", ] } -wgpu = "28.0" +wgpu = "29.0" winit = { version = "0.30" } diff --git a/code/showcase/pong/Cargo.toml b/code/showcase/pong/Cargo.toml index 6a8952974..f80554437 100644 --- a/code/showcase/pong/Cargo.toml +++ b/code/showcase/pong/Cargo.toml @@ -14,7 +14,7 @@ winit = { version = "0.30", features = ["android-native-activity"] } bytemuck = { version = "1.24", features = [ "derive" ] } cgmath = "0.18" pollster = "0.3" -wgpu = { version = "28.0", features = ["spirv"]} +wgpu = { version = "29.0", features = ["spirv"]} wgpu_glyph = { version = "0.22", git = "https://github.com/hecrj/wgpu_glyph.git" } rand = "0.8" rodio = { version = "0.16", default-features = false, features = ["wav"] } @@ -33,11 +33,11 @@ web-sys = { version = "0.3", features = [ "Window", "Element", ]} -wgpu = { version = "28.0", features = ["spirv", "webgl"]} +wgpu = { version = "29.0", features = ["spirv", "webgl"]} [build-dependencies] anyhow = "1.0" fs_extra = "1.2" glob = "0.3" rayon = "1.4" -naga = { version = "28.0", features = ["glsl-in", "spv-out", "wgsl-out"]} +naga = { version = "29.0", features = ["glsl-in", "spv-out", "wgsl-out"]} diff --git a/code/showcase/pong/src/render/mod.rs b/code/showcase/pong/src/render/mod.rs index e86adc76c..b12dd2465 100644 --- a/code/showcase/pong/src/render/mod.rs +++ b/code/showcase/pong/src/render/mod.rs @@ -40,12 +40,15 @@ impl<'a> Render<'a> { log::warn!("size: {:?}", size); // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); diff --git a/code/showcase/snow/src/main.rs b/code/showcase/snow/src/main.rs index 91e7d452f..a41a277e7 100644 --- a/code/showcase/snow/src/main.rs +++ b/code/showcase/snow/src/main.rs @@ -141,7 +141,7 @@ impl framework::Demo for Snow { .device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&particle_layout], + bind_group_layouts: &[Some(&particle_layout)], immediate_size: 0, }); @@ -209,7 +209,7 @@ impl framework::Demo for Snow { .device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&uniforms_bind_group_layout], + bind_group_layouts: &[Some(&uniforms_bind_group_layout)], immediate_size: 0, }); @@ -341,9 +341,21 @@ impl framework::Demo for Snow { fn render(&mut self, display: &mut framework::Display) { let frame = match display.surface().get_current_texture() { - Ok(frame) => frame, - Err(wgpu::SurfaceError::Outdated) => return, - Err(e) => panic!("{}", e), + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + display.configure(); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => return, + wgpu::CurrentSurfaceTexture::Outdated => { + display.configure(); + return; + } + wgpu::CurrentSurfaceTexture::Lost => { + panic!("Context lost"); + } }; let view = frame.texture.create_view(&Default::default()); diff --git a/code/showcase/stencil/src/main.rs b/code/showcase/stencil/src/main.rs index db6c1a404..c63967597 100644 --- a/code/showcase/stencil/src/main.rs +++ b/code/showcase/stencil/src/main.rs @@ -211,7 +211,7 @@ impl Demo for Stencil { .device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("mask_pipeline_layout"), - bind_group_layouts: &[&mask_bind_group_layout], + bind_group_layouts: &[Some(&mask_bind_group_layout)], immediate_size: 0, }); @@ -223,8 +223,8 @@ impl Demo for Stencil { .cull_mode(Some(wgpu::Face::Back)) .depth_stencil(wgpu::DepthStencilState { format: depth_stencil_format, - depth_write_enabled: false, - depth_compare: wgpu::CompareFunction::Always, + depth_write_enabled: Some(false), + depth_compare: Some(wgpu::CompareFunction::Always), stencil: wgpu::StencilState { write_mask: 0xFF, read_mask: 0xFF, @@ -255,7 +255,7 @@ impl Demo for Stencil { let model_pipeline_layout = display.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("model_pipeline_layout"), - bind_group_layouts: &[&camera_layout, material_binder.layout()], + bind_group_layouts: &[Some(&camera_layout), Some(material_binder.layout())], immediate_size: 0, }); let model_shader = wgpu::include_wgsl!("model.wgsl"); @@ -271,8 +271,8 @@ impl Demo for Stencil { }) .depth_stencil(wgpu::DepthStencilState { format: depth_stencil.format(), - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }) @@ -292,8 +292,8 @@ impl Demo for Stencil { }) .depth_stencil(wgpu::DepthStencilState { format: depth_stencil.format(), - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState { read_mask: 0xFF, write_mask: 0xFF, @@ -375,9 +375,21 @@ impl Demo for Stencil { fn render(&mut self, display: &mut framework::Display) { let frame = match display.surface().get_current_texture() { - Ok(frame) => frame, - Err(wgpu::SurfaceError::Outdated) => return, - Err(e) => panic!("{}", e), + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + display.configure(); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => return, + wgpu::CurrentSurfaceTexture::Outdated => { + display.configure(); + return; + } + wgpu::CurrentSurfaceTexture::Lost => { + panic!("Context lost"); + } }; let view = frame.texture.create_view(&Default::default()); diff --git a/code/showcase/threading/Cargo.toml b/code/showcase/threading/Cargo.toml index bb2837a71..0610c5aaf 100644 --- a/code/showcase/threading/Cargo.toml +++ b/code/showcase/threading/Cargo.toml @@ -16,7 +16,7 @@ pollster = "0.3" log = "0.4" rayon = "1.4" # NEW! tobj = { version = "3.2", default-features = false, features = ["async"]} -wgpu = { version = "28.0"} +wgpu = { version = "29.0"} winit = { version = "0.30", features = ["android-native-activity"] } instant = "0.1" async-std = "1" @@ -30,7 +30,7 @@ features = ["png", "jpeg"] reqwest = { version = "0.11" } console_error_panic_hook = "0.1" console_log = "1.0" -wgpu = { version = "28.0", features = ["webgl"]} +wgpu = { version = "29.0", features = ["webgl"]} wasm-bindgen = "0.2" wasm-bindgen-futures = "0.4" web-sys = { version = "0.3", features = [ diff --git a/code/showcase/threading/src/lib.rs b/code/showcase/threading/src/lib.rs index cadc9a3b1..bdfb0eedb 100644 --- a/code/showcase/threading/src/lib.rs +++ b/code/showcase/threading/src/lib.rs @@ -208,8 +208,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -231,12 +231,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -453,9 +456,9 @@ impl State { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], immediate_size: 0, }); @@ -478,7 +481,10 @@ impl State { let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[ + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), + ], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -610,7 +616,7 @@ impl State { ); } - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -618,7 +624,28 @@ impl State { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -800,13 +827,10 @@ impl ApplicationHandler for App { state.update(dt); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/code/showcase/windowless/Cargo.toml b/code/showcase/windowless/Cargo.toml index 47ce31ef4..a77cf437c 100644 --- a/code/showcase/windowless/Cargo.toml +++ b/code/showcase/windowless/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" [dependencies] image = "0.24" -wgpu = { version = "28.0", features = ["spirv"] } +wgpu = { version = "29.0", features = ["spirv"] } pollster = "0.3" futures-intrusive = "0.4" diff --git a/code/showcase/windowless/src/main.rs b/code/showcase/windowless/src/main.rs index 65057a356..e06427c5e 100644 --- a/code/showcase/windowless/src/main.rs +++ b/code/showcase/windowless/src/main.rs @@ -1,10 +1,7 @@ use pollster::FutureExt; async fn run() { - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { - backends: wgpu::Backends::all(), - ..Default::default() - }); + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); let adapter = instance .request_adapter(&wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::default(), diff --git a/docs/beginner/tutorial2-surface/README.md b/docs/beginner/tutorial2-surface/README.md index 5b203640e..2b59a0453 100644 --- a/docs/beginner/tutorial2-surface/README.md +++ b/docs/beginner/tutorial2-surface/README.md @@ -32,12 +32,15 @@ impl State { // The instance is a handle to our GPU // BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] backends: wgpu::Backends::GL, - ..Default::default() + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, }); let surface = instance.create_surface(window.clone()).unwrap(); @@ -289,7 +292,7 @@ Here's where the magic happens. First, we need to get a frame to render to. ```rust // impl State -fn render(&mut self) -> Result<(), wgpu::SurfaceError> { +fn render(&mut self) -> anyhow::Result<()> { self.window.request_redraw(); // We can't render unless the surface is configured @@ -297,7 +300,28 @@ fn render(&mut self) -> Result<(), wgpu::SurfaceError> { return Ok(()); } - let output = self.surface.get_current_texture()?; + let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; ``` The `get_current_texture` function will wait for the `surface` to provide a new `SurfaceTexture` that we will render to. We'll store this in `output` for later. @@ -376,13 +400,10 @@ We need to update the event loop again to call this method. We'll also call `upd state.update(); match state.render() { Ok(_) => {} - // Reconfigure the surface if it's lost or outdated - Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => { - let size = state.window.inner_size(); - state.resize(size.width, size.height); - } Err(e) => { - log::error!("Unable to render {}", e); + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); } } } diff --git a/docs/beginner/tutorial5-textures/README.md b/docs/beginner/tutorial5-textures/README.md index def3e0e31..8e70d2098 100644 --- a/docs/beginner/tutorial5-textures/README.md +++ b/docs/beginner/tutorial5-textures/README.md @@ -313,7 +313,7 @@ async fn new(...) { let render_pipeline_layout = device.create_pipeline_layout( &wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), - bind_group_layouts: &[&texture_bind_group_layout], // NEW! + bind_group_layouts: &[Some(&texture_bind_group_layout)], // NEW! immediate_size: 0, } ); diff --git a/docs/beginner/tutorial6-uniforms/README.md b/docs/beginner/tutorial6-uniforms/README.md index 54c1dc5be..e7c86b619 100644 --- a/docs/beginner/tutorial6-uniforms/README.md +++ b/docs/beginner/tutorial6-uniforms/README.md @@ -191,8 +191,8 @@ let render_pipeline_layout = device.create_pipeline_layout( &wgpu::PipelineLayoutDescriptor { label: Some("Render Pipeline Layout"), bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), ], immediate_size: 0, } diff --git a/docs/beginner/tutorial8-depth/README.md b/docs/beginner/tutorial8-depth/README.md index 8a539f80a..dabcae321 100644 --- a/docs/beginner/tutorial8-depth/README.md +++ b/docs/beginner/tutorial8-depth/README.md @@ -85,8 +85,8 @@ let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescrip // ... depth_stencil: Some(wgpu::DepthStencilState { format: texture::Texture::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, // 1. + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), // 1. stencil: wgpu::StencilState::default(), // 2. bias: wgpu::DepthBiasState::default(), }), diff --git a/docs/intermediate/tutorial10-lighting/README.md b/docs/intermediate/tutorial10-lighting/README.md index 349d20404..fcf70d781 100644 --- a/docs/intermediate/tutorial10-lighting/README.md +++ b/docs/intermediate/tutorial10-lighting/README.md @@ -98,9 +98,9 @@ Add those to `State` and also update the `render_pipeline_layout`. ```rust let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { bind_group_layouts: &[ - &texture_bind_group_layout, - &camera_bind_group_layout, - &light_bind_group_layout, + Some(&texture_bind_group_layout), + Some(&camera_bind_group_layout), + Some(&light_bind_group_layout), ], }); ``` @@ -171,8 +171,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), @@ -302,7 +302,7 @@ With that done, we can create another render pipeline for our light. let light_render_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Light Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &light_bind_group_layout], + bind_group_layouts: &[Some(&camera_bind_group_layout), Some(&light_bind_group_layout)], immediate_size: 0, }); let shader = wgpu::ShaderModuleDescriptor { @@ -457,7 +457,7 @@ Finally, we want to add Light rendering to our render passes. ```rust impl State { // ... - fn render(&mut self) -> Result<(), wgpu::SurfaceError> { + fn render(&mut self) -> anyhow::Result<()> { // ... render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..)); diff --git a/docs/intermediate/tutorial13-hdr/readme.md b/docs/intermediate/tutorial13-hdr/readme.md index 4f9f29dbb..a84daffeb 100644 --- a/docs/intermediate/tutorial13-hdr/readme.md +++ b/docs/intermediate/tutorial13-hdr/readme.md @@ -98,7 +98,7 @@ impl HdrPipeline { let shader = wgpu::include_wgsl!("hdr.wgsl"); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&layout], + bind_group_layouts: &[Some(&layout)], immediate_size: 0, }); @@ -538,7 +538,7 @@ impl HdrLoader { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&equirect_layout], + bind_group_layouts: &[Some(&equirect_layout)], immediate_size: 0, }); @@ -863,7 +863,7 @@ Now that we have the bindgroup, we need a render pipeline to render the skybox. let sky_pipeline = { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("Sky Pipeline Layout"), - bind_group_layouts: &[&camera_bind_group_layout, &environment_layout], + bind_group_layouts: &[Some(&camera_bind_group_layout), Some(&environment_layout)], immediate_size: 0, }); let shader = wgpu::include_wgsl!("sky.wgsl"); @@ -901,8 +901,8 @@ fn create_render_pipeline( }, depth_stencil: depth_format.map(|format| wgpu::DepthStencilState { format, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::LessEqual, // UDPATED! + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::LessEqual), // UDPATED! stencil: wgpu::StencilState::default(), bias: wgpu::DepthBiasState::default(), }), diff --git a/docs/news/29.0/readme.md b/docs/news/29.0/readme.md new file mode 100644 index 000000000..2a3577507 --- /dev/null +++ b/docs/news/29.0/readme.md @@ -0,0 +1,33 @@ +# Update to Wgpu 29.0 + +* bind_groups in PipelineDescriptor are now Option<&wgpu::BindGroupLayout> +* current_surface returns CurrentSurface enum +* InstanceDescriptor changes + +```rust +let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + #[cfg(not(target_arch = "wasm32"))] + backends: wgpu::Backends::PRIMARY, + #[cfg(target_arch = "wasm32")] + backends: wgpu::Backends::GL, + flags: Default::default(), + memory_budget_thresholds: Default::default(), + backend_options: Default::default(), + display: None, + }); +``` + +```rust +match state.render() { + Ok(_) => {} + Err(e) => { + // Log the error and exit gracefully + log::error!("{e}"); + event_loop.exit(); + } + } + ``` + +```rust +let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); +``` \ No newline at end of file diff --git a/docs/news/pre-0.12/readme.md b/docs/news/pre-0.12/readme.md index ece549fc5..7fcc0ef8c 100644 --- a/docs/news/pre-0.12/readme.md +++ b/docs/news/pre-0.12/readme.md @@ -13,7 +13,28 @@ If you want to check out the demo, just head over to [the write up](../showcase/ `SwapchainFrame` is no longer a thing. Instead `get_current_texture` will return a `SurfaceTexture` directly. This means that getting a frame to draw to looks somethings like this: ```rust -let output = self.surface.get_current_texture()?; +let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -61,7 +82,28 @@ if width > 0 && height > 0 { Finally, getting a `SurfaceTexture` to draw to will use the surface directly. ```rust -let output = self.surface.get_current_texture()?; +let output = match self.surface.get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + self.surface.configure(&self.device, &self.config); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => { + // Skip this frame + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Outdated => { + self.surface.configure(&self.device, &self.config); + return Ok(()); + } + wgpu::CurrentSurfaceTexture::Lost => { + // You could recreate the devices and all resources + // created with it here, but we'll just bail + anyhow::bail!("Lost device"); + } + }; let view = output .texture .create_view(&wgpu::TextureViewDescriptor::default()); diff --git a/docs/showcase/mipmaps/readme.md b/docs/showcase/mipmaps/readme.md index e35c19f52..90775415a 100644 --- a/docs/showcase/mipmaps/readme.md +++ b/docs/showcase/mipmaps/readme.md @@ -492,7 +492,7 @@ impl Mipmapper { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[&storage_texture_layout], + bind_group_layouts: &[Some(&storage_texture_layout)], immediate_size: 0, }); let compute_module = device.create_shader_module(wgpu::include_wgsl!("mipmap.wgsl")); diff --git a/docs/showcase/stencil/readme.md b/docs/showcase/stencil/readme.md index e68ff7871..e1159a935 100644 --- a/docs/showcase/stencil/readme.md +++ b/docs/showcase/stencil/readme.md @@ -88,7 +88,7 @@ let mask_pipeline_layout = .device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("mask_pipeline_layout"), - bind_group_layouts: &[&mask_bind_group_layout], + bind_group_layouts: &[Some(&mask_bind_group_layout)], immediate_size: 0, }); @@ -100,8 +100,8 @@ let mask_pipeline = framework::RenderPipelineBuilder::new() .cull_mode(Some(wgpu::Face::Back)) .depth_stencil(wgpu::DepthStencilState { format: depth_stencil_format, - depth_write_enabled: false, - depth_compare: wgpu::CompareFunction::Always, + depth_write_enabled: Some(false), + depth_compare: Some(wgpu::CompareFunction::Always), stencil: wgpu::StencilState { write_mask: 0xFF, read_mask: 0xFF, @@ -234,8 +234,8 @@ let hidden_pipeline = framework::RenderPipelineBuilder::new() }) .depth_stencil(wgpu::DepthStencilState { format: depth_stencil.format(), - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, + depth_write_enabled: Some(true), + depth_compare: Some(wgpu::CompareFunction::Less), stencil: wgpu::StencilState { // Read all bits read_mask: 0xFF, From 5d5150a5a74cdf3a35be3bd907e21e8fff959ff5 Mon Sep 17 00:00:00 2001 From: Benjamin Hansen Date: Tue, 24 Mar 2026 21:43:39 -0600 Subject: [PATCH 2/2] wrote news article for 29.0 --- docs/.vuepress/config.js | 1 + docs/beginner/tutorial2-surface/README.md | 16 ++- docs/news/29.0/readme.md | 121 +++++++++++++++++++--- 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 6dbb4161f..6739aeeb5 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -68,6 +68,7 @@ export default defineUserConfig({ text: "News", collapsable: true, children: [ + "/news/29.0/", "/news/vuepress-v2/", "/news/28.0/", "/news/27.0/", diff --git a/docs/beginner/tutorial2-surface/README.md b/docs/beginner/tutorial2-surface/README.md index 2b59a0453..49008185a 100644 --- a/docs/beginner/tutorial2-surface/README.md +++ b/docs/beginner/tutorial2-surface/README.md @@ -55,6 +55,18 @@ impl State { // ... } + + // ... +} +``` + +Note: if you specify a display handle via the `display` field on `InstanceDescriptor` +the display you pass into `create_surface()` must match up with it. You can define +the `display` on the `InstanceDescriptor` struct directly or with a convenience +method: + +```rust +let instance = Instance::new(InstanceDescriptor::new_with_display_handle(Box::new(event_loop.owned_display_handle()))); ``` ### Instance and Adapter @@ -75,6 +87,8 @@ The options I've passed to `request_adapter` aren't guaranteed to work for all d ```rust let adapter = instance .enumerate_adapters(wgpu::Backends::all()) + .await + .into_iter() .filter(|adapter| { // Check if this adapter supports our surface adapter.is_surface_supported(&surface) @@ -91,7 +105,7 @@ For more fields you can use to refine your search, [check out the docs](https:// -### The Surface +### What is the Surface? The `surface` is the part of the window that we draw to. We need it to draw directly to the screen. Our `window` needs to implement [raw-window-handle](https://crates.io/crates/raw-window-handle)'s `HasRawWindowHandle` trait to create a surface. Fortunately, winit's `Window` fits the bill. We also need it to request our `adapter`. diff --git a/docs/news/29.0/readme.md b/docs/news/29.0/readme.md index 2a3577507..0fc835cbf 100644 --- a/docs/news/29.0/readme.md +++ b/docs/news/29.0/readme.md @@ -1,11 +1,60 @@ # Update to Wgpu 29.0 -* bind_groups in PipelineDescriptor are now Option<&wgpu::BindGroupLayout> -* current_surface returns CurrentSurface enum -* InstanceDescriptor changes +Another Wgpu update has come! A few things we should go over. + +## Creating PipelineLayouts + +The `bind_groups` in `PipelineDescriptor` are now `Option<&wgpu::BindGroupLayout>` +This means that when defining a pipeline layout you need to wrap your bind group +layouts with `Some()`. + +```rust + let model_pipeline_layout = + display.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("model_pipeline_layout"), + bind_group_layouts: &[Some(&camera_layout), Some(material_binder.layout())], + immediate_size: 0, + }); +``` + +This means that you can have your bindings use consistent group numbers. For +example you can have your camera data be `@group(0)` material data always be +`@group(1)` even if the shader doesn't use the camera. + +## CurrentSurfaceTexture + +The `current_surface()` function now returns `CurrentSurfaceTexture` enum. This means +we have to change our render logic to handle this new way of working. + +```rust + let frame = match display.surface().get_current_texture() { + wgpu::CurrentSurfaceTexture::Success(surface_texture) => surface_texture, + wgpu::CurrentSurfaceTexture::Suboptimal(surface_texture) => { + display.configure(); + surface_texture + } + wgpu::CurrentSurfaceTexture::Timeout + | wgpu::CurrentSurfaceTexture::Occluded + | wgpu::CurrentSurfaceTexture::Validation => return, + wgpu::CurrentSurfaceTexture::Outdated => { + display.configure(); + return; + } + wgpu::CurrentSurfaceTexture::Lost => { + panic!("Context lost"); + } + }; +``` + +## Instance creation changes + +The `InstanceDescriptor` struct now longer has a `Default` implementation. This is +because it now requires you to specify whether you want to use a `display` handle. +If you specify a `display` here, you don't have to use a matching one when you +create a `surface`. ```rust -let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { #[cfg(not(target_arch = "wasm32"))] backends: wgpu::Backends::PRIMARY, #[cfg(target_arch = "wasm32")] @@ -17,17 +66,55 @@ let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { }); ``` -```rust -match state.render() { - Ok(_) => {} - Err(e) => { - // Log the error and exit gracefully - log::error!("{e}"); - event_loop.exit(); - } - } - ``` +If you don't want to specify all the fields you can use these convenience methods. -```rust -let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle()); -``` \ No newline at end of file +* `new_with_display_handle` +* `new_with_display_handle_from_env` +* `new_without_display_handle` +* `new_without_display_handle_from_env` + +There are lots of other changes that you can check out in +[the official release](https://github.com/gfx-rs/wgpu/releases/tag/v29.0.0) + +## Supporters + +A special thanks to these supporters! + +* Craft Links +* 大典 加藤 +* Dude +* David Laban +* Alexander Kabirov +* Bernard Llanos +* Eliot Bolduc +* IC +* Nico Arbogast +* Ian Gowen +* Aron Granberg +* 折登 樹 +* Julius Liu +* Jani Turkia +* Lions Heart +* Feng Liang +* Paul E Hansen +* Gunstein Vatnar +* Youngsuk Kim +* Danny McGee +* charlesk +* yutani +* Ben Anderson +* Ken +* Ryan +* ツナマヨ +* Tema +* dadofboi +* Lennart +* Felix +* Davide Prati +* Andrea Postal +* Zeh Fernando +* Filip +* Thunk + +If this helped you out and you want to support checkout +[my patreon](https://patreon.com/sotrh) or [my kofi account](https://ko-fi.com/sotrh)!