commit de0bcdb66868f4106880f582c0c14944e05fbf94 parent b9f589ffe2173b236735cc134ba1f6965f4121da Author: Erich Gubler <erichdongubler@gmail.com> Date: Fri, 3 Oct 2025 18:08:29 +0000 Bug 1991551 - build(webgpu): update WGPU to 8c4aebc0c1b75e3f7412dfc180745a0717fc30ec r=webgpu-reviewers,supply-chain-reviewers,nical Differential Revision: https://phabricator.services.mozilla.com/D266858 Diffstat:
115 files changed, 5452 insertions(+), 2234 deletions(-)
diff --git a/.cargo/config.toml.in b/.cargo/config.toml.in @@ -40,9 +40,9 @@ git = "https://github.com/franziskuskiefer/cose-rust" rev = "43c22248d136c8b38fe42ea709d08da6355cf04b" replace-with = "vendored-sources" -[source."git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24"] +[source."git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec"] git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" replace-with = "vendored-sources" [source."git+https://github.com/glandium/allocator-api2?rev=ad5f3d56a5a4519eff52af4ff85293431466ef5c"] diff --git a/Cargo.lock b/Cargo.lock @@ -2953,7 +2953,7 @@ name = "hashlink" version = "0.10.0" source = "git+https://github.com/erichdongubler-contrib/hashlink?rev=76dc47a12af5829c1e8bf4834e38b410dec2aeff#76dc47a12af5829c1e8bf4834e38b410dec2aeff" dependencies = [ - "hashbrown 0.15.999", + "hashbrown 0.16.0", ] [[package]] @@ -4667,7 +4667,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664" [[package]] name = "naga" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "arrayvec", "bit-set", @@ -4676,7 +4676,7 @@ dependencies = [ "cfg_aliases", "codespan-reporting", "half 2.5.0", - "hashbrown 0.15.999", + "hashbrown 0.16.0", "hexf-parse", "indexmap", "libm", @@ -5869,9 +5869,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64 0.22.1", "bitflags 2.9.0", @@ -7742,7 +7742,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "arrayvec", "bit-set", @@ -7751,7 +7751,7 @@ dependencies = [ "bytemuck", "cfg_aliases", "document-features", - "hashbrown 0.15.999", + "hashbrown 0.16.0", "indexmap", "log", "naga", @@ -7772,7 +7772,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "wgpu-hal", ] @@ -7780,7 +7780,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-windows-linux-android" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "wgpu-hal", ] @@ -7788,7 +7788,7 @@ dependencies = [ [[package]] name = "wgpu-hal" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "android_system_properties", "arrayvec", @@ -7803,7 +7803,7 @@ dependencies = [ "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hashbrown 0.15.999", + "hashbrown 0.16.0", "libc", "libloading", "log", @@ -7826,7 +7826,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "26.0.0" -source = "git+https://github.com/gfx-rs/wgpu?rev=ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24#ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +source = "git+https://github.com/gfx-rs/wgpu?rev=8c4aebc0c1b75e3f7412dfc180745a0717fc30ec#8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" dependencies = [ "bitflags 2.9.0", "bytemuck", diff --git a/gfx/wgpu_bindings/Cargo.toml b/gfx/wgpu_bindings/Cargo.toml @@ -17,7 +17,7 @@ default = [] [dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" features = ["serde", "trace", "strict_asserts", "wgsl", "api_log_info"] # We want the wgpu-core Metal backend on macOS and iOS. @@ -25,32 +25,32 @@ features = ["serde", "trace", "strict_asserts", "wgsl", "api_log_info"] [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" features = ["metal"] # We want the wgpu-core Direct3D backends on Windows. [target.'cfg(windows)'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" features = ["dx12"] # We want the wgpu-core Vulkan backend on Linux and Windows. [target.'cfg(any(windows, all(unix, not(any(target_os = "macos", target_os = "ios")))))'.dependencies.wgc] package = "wgpu-core" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" features = ["vulkan"] [dependencies.wgt] package = "wgpu-types" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" [dependencies.wgh] package = "wgpu-hal" git = "https://github.com/gfx-rs/wgpu" -rev = "ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +rev = "8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" features = ["device_lost_panic", "internal_error_panic"] [target.'cfg(windows)'.dependencies] diff --git a/gfx/wgpu_bindings/moz.yaml b/gfx/wgpu_bindings/moz.yaml @@ -8,8 +8,8 @@ origin: name: wgpu description: A cross-platform pure-Rust graphics API, modeled on the WebGPU standard url: https://github.com/gfx-rs/wgpu - release: commit ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24 - revision: ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24 + release: 8c4aebc0c1b75e3f7412dfc180745a0717fc30ec (2025-09-29T17:15:32Z). + revision: 8c4aebc0c1b75e3f7412dfc180745a0717fc30ec license: ['MIT', 'Apache-2.0'] updatebot: diff --git a/gfx/wr/Cargo.lock b/gfx/wr/Cargo.lock @@ -2630,9 +2630,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", "bitflags 2.4.2", diff --git a/gfx/wr/webrender/Cargo.toml b/gfx/wr/webrender/Cargo.toml @@ -41,7 +41,7 @@ num-traits = "0.2" plane-split = "0.18" png = { optional = true, version = "0.16" } rayon = "1" -ron = { optional = true, version = "0.10.0" } +ron = { optional = true, version = "0.11.0" } serde = { optional = true, version = "1.0", features = ["serde_derive"] } smallvec = "1" api = { version = "0.62.0", path = "../webrender_api", package = "webrender_api" } diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml @@ -4302,7 +4302,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.net2]] @@ -6817,7 +6817,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.wgpu-core-deps-apple]] @@ -6838,7 +6838,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.wgpu-core-deps-windows-linux-android]] @@ -6859,7 +6859,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.wgpu-hal]] @@ -6958,7 +6958,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.wgpu-types]] @@ -7052,7 +7052,7 @@ who = [ "Erich Gubler <erichdongubler@gmail.com>", ] criteria = "safe-to-deploy" -delta = "26.0.0 -> 26.0.0@git:ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24" +delta = "26.0.0 -> 26.0.0@git:8c4aebc0c1b75e3f7412dfc180745a0717fc30ec" importable = false [[audits.whatsys]] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/operation/vertex_state/correctness/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/operation/vertex_state/correctness/cts.https.html.ini @@ -1,174 +1,95 @@ [cts.https.html?q=webgpu:api,operation,vertex_state,correctness:array_stride_zero:*] implementation-status: if os == "linux": backlog - if os == "mac": backlog [:format="float16"] - expected: - if os == "mac": FAIL [:format="float16x2"] - expected: - if os == "mac": FAIL [:format="float16x4"] - expected: - if os == "mac": FAIL [:format="float32"] - expected: - if os == "mac": FAIL [:format="float32x2"] - expected: - if os == "mac": FAIL [:format="float32x3"] - expected: - if os == "mac": FAIL [:format="float32x4"] - expected: - if os == "mac": FAIL [:format="sint16"] - expected: - if os == "mac": FAIL [:format="sint16x2"] - expected: - if os == "mac": FAIL [:format="sint16x4"] - expected: - if os == "mac": FAIL [:format="sint32"] - expected: - if os == "mac": FAIL [:format="sint32x2"] - expected: - if os == "mac": FAIL [:format="sint32x3"] - expected: - if os == "mac": FAIL [:format="sint32x4"] - expected: - if os == "mac": FAIL [:format="sint8"] - expected: - if os == "mac": FAIL [:format="sint8x2"] - expected: - if os == "mac": FAIL [:format="sint8x4"] - expected: - if os == "mac": FAIL [:format="snorm16"] - expected: - if os == "mac": FAIL [:format="snorm16x2"] expected: if os == "linux": FAIL - if os == "mac": FAIL [:format="snorm16x4"] expected: if os == "linux": FAIL - if os == "mac": FAIL [:format="snorm8"] - expected: - if os == "mac": FAIL [:format="snorm8x2"] expected: if os == "linux": FAIL - if os == "mac": FAIL [:format="snorm8x4"] expected: if os == "linux": FAIL - if os == "mac": FAIL [:format="uint16"] - expected: - if os == "mac": FAIL [:format="uint16x2"] - expected: - if os == "mac": FAIL [:format="uint16x4"] - expected: - if os == "mac": FAIL [:format="uint32"] - expected: - if os == "mac": FAIL [:format="uint32x2"] - expected: - if os == "mac": FAIL [:format="uint32x3"] - expected: - if os == "mac": FAIL [:format="uint32x4"] - expected: - if os == "mac": FAIL [:format="uint8"] - expected: - if os == "mac": FAIL [:format="uint8x2"] - expected: - if os == "mac": FAIL [:format="uint8x4"] - expected: - if os == "mac": FAIL [:format="unorm10-10-10-2"] - expected: - if os == "mac": FAIL [:format="unorm16"] - expected: - if os == "mac": FAIL [:format="unorm16x2"] - expected: - if os == "mac": FAIL [:format="unorm16x4"] - expected: - if os == "mac": FAIL [:format="unorm8"] - expected: - if os == "mac": FAIL [:format="unorm8x2"] - expected: - if os == "mac": FAIL [:format="unorm8x4"] - expected: - if os == "mac": FAIL [:format="unorm8x4-bgra"] - expected: - if os == "mac": FAIL [cts.https.html?q=webgpu:api,operation,vertex_state,correctness:buffers_with_varying_step_mode:*] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/encoding/cmds/copyBufferToBuffer/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/encoding/cmds/copyBufferToBuffer/cts.https.html.ini @@ -3,11 +3,9 @@ [cts.https.html?q=webgpu:api,validation,encoding,cmds,copyBufferToBuffer:buffer_state:*] - implementation-status: backlog [:srcBufferState="destroyed";dstBufferState="destroyed"] [:srcBufferState="destroyed";dstBufferState="invalid"] - expected: FAIL [:srcBufferState="destroyed";dstBufferState="valid"] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/image_copy/layout_related/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/image_copy/layout_related/cts.https.html.ini @@ -3586,117 +3586,231 @@ [cts.https.html?q=webgpu:api,validation,image_copy,layout_related:required_bytes_in_copy:*] implementation-status: backlog + expected: + if os == "mac": TIMEOUT [:method="CopyB2T";format="astc-10x10-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x10-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x10-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x10-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x8-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x8-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x8-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-10x8-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x10-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x10-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x10-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x10-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x12-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x12-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x12-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-12x12-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-4x4-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-4x4-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-4x4-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-4x4-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x4-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x4-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x4-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x4-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-5x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-6x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x8-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x8-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x8-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="astc-8x8-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc1-rgba-unorm";dimension="2d"] expected: FAIL @@ -3720,67 +3834,130 @@ expected: FAIL [:method="CopyB2T";format="bc2-rgba-unorm-srgb";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc3-rgba-unorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc3-rgba-unorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc3-rgba-unorm-srgb";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc3-rgba-unorm-srgb";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc4-r-snorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc4-r-snorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc4-r-unorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc4-r-unorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc5-rg-snorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc5-rg-snorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc5-rg-unorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc5-rg-unorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc6h-rgb-float";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc6h-rgb-float";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc6h-rgb-ufloat";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc6h-rgb-ufloat";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc7-rgba-unorm";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc7-rgba-unorm";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc7-rgba-unorm-srgb";dimension="2d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bc7-rgba-unorm-srgb";dimension="3d"] - expected: FAIL + expected: + if os == "win": FAIL + if os == "linux": FAIL + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="bgra8unorm";dimension="1d"] @@ -3801,24 +3978,44 @@ [:method="CopyB2T";format="depth16unorm";dimension="2d"] [:method="CopyB2T";format="eac-r11snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="eac-r11unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="eac-rg11snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="eac-rg11unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgb8a1unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgb8a1unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgb8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgb8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgba8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="etc2-rgba8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyB2T";format="r16float";dimension="1d"] @@ -4139,456 +4336,908 @@ [:method="CopyB2T";format="stencil8";dimension="2d"] [:method="CopyT2B";format="astc-10x10-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x10-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x10-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x10-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x8-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x8-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x8-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-10x8-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x10-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x10-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x10-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x10-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x12-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x12-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x12-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-12x12-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-4x4-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-4x4-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-4x4-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-4x4-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x4-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x4-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x4-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x4-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-5x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-6x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x5-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x5-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x5-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x5-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x6-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x6-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x6-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x6-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x8-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x8-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x8-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="astc-8x8-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc1-rgba-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc1-rgba-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc1-rgba-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc1-rgba-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc2-rgba-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc2-rgba-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc2-rgba-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc2-rgba-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc3-rgba-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc3-rgba-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc3-rgba-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc3-rgba-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc4-r-snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc4-r-snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc4-r-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc4-r-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc5-rg-snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc5-rg-snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc5-rg-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc5-rg-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc6h-rgb-float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc6h-rgb-float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc6h-rgb-ufloat";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc6h-rgb-ufloat";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc7-rgba-unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc7-rgba-unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc7-rgba-unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bc7-rgba-unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm-srgb";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="bgra8unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="depth16unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="depth32float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="eac-r11snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="eac-r11unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="eac-rg11snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="eac-rg11unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgb8a1unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgb8a1unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgb8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgb8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgba8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="etc2-rgba8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r16unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r32uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="r8unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg11b10ufloat";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg11b10ufloat";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg11b10ufloat";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg16unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg32uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rg8unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb10a2unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb9e5ufloat";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb9e5ufloat";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgb9e5ufloat";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba16unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32float";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32float";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32float";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba32uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8sint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8sint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8sint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8snorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8snorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8snorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8uint";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8uint";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8uint";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm-srgb";dimension="1d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm-srgb";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="rgba8unorm-srgb";dimension="3d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="CopyT2B";format="stencil8";dimension="2d"] + expected: + if os == "mac": [TIMEOUT, NOTRUN] [:method="WriteTexture";format="astc-10x10-unorm";dimension="2d"] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/render_pipeline/vertex_state/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/render_pipeline/vertex_state/cts.https.html.ini @@ -1,5 +1,9 @@ [cts.https.html?q=webgpu:api,validation,render_pipeline,vertex_state:many_attributes_overlapping:*] + implementation-status: + if os == "mac": backlog [:] + expected: + if os == "mac": FAIL [cts.https.html?q=webgpu:api,validation,render_pipeline,vertex_state:max_vertex_attribute_limit:*] @@ -21,87 +25,171 @@ [cts.https.html?q=webgpu:api,validation,render_pipeline,vertex_state:vertex_attribute_contained_in_stride:*] + implementation-status: + if os == "mac": backlog [:format="float16"] + expected: + if os == "mac": FAIL [:format="float16x2"] + expected: + if os == "mac": FAIL [:format="float16x4"] + expected: + if os == "mac": FAIL [:format="float32"] + expected: + if os == "mac": FAIL [:format="float32x2"] + expected: + if os == "mac": FAIL [:format="float32x3"] + expected: + if os == "mac": FAIL [:format="float32x4"] + expected: + if os == "mac": FAIL [:format="sint16"] + expected: + if os == "mac": FAIL [:format="sint16x2"] + expected: + if os == "mac": FAIL [:format="sint16x4"] + expected: + if os == "mac": FAIL [:format="sint32"] + expected: + if os == "mac": FAIL [:format="sint32x2"] + expected: + if os == "mac": FAIL [:format="sint32x3"] + expected: + if os == "mac": FAIL [:format="sint32x4"] + expected: + if os == "mac": FAIL [:format="sint8"] + expected: + if os == "mac": FAIL [:format="sint8x2"] + expected: + if os == "mac": FAIL [:format="sint8x4"] + expected: + if os == "mac": FAIL [:format="snorm16"] + expected: + if os == "mac": FAIL [:format="snorm16x2"] + expected: + if os == "mac": FAIL [:format="snorm16x4"] + expected: + if os == "mac": FAIL [:format="snorm8"] + expected: + if os == "mac": FAIL [:format="snorm8x2"] + expected: + if os == "mac": FAIL [:format="snorm8x4"] + expected: + if os == "mac": FAIL [:format="uint16"] + expected: + if os == "mac": FAIL [:format="uint16x2"] + expected: + if os == "mac": FAIL [:format="uint16x4"] + expected: + if os == "mac": FAIL [:format="uint32"] + expected: + if os == "mac": FAIL [:format="uint32x2"] + expected: + if os == "mac": FAIL [:format="uint32x3"] + expected: + if os == "mac": FAIL [:format="uint32x4"] + expected: + if os == "mac": FAIL [:format="uint8"] + expected: + if os == "mac": FAIL [:format="uint8x2"] + expected: + if os == "mac": FAIL [:format="uint8x4"] + expected: + if os == "mac": FAIL [:format="unorm10-10-10-2"] + expected: + if os == "mac": FAIL [:format="unorm16"] + expected: + if os == "mac": FAIL [:format="unorm16x2"] + expected: + if os == "mac": FAIL [:format="unorm16x4"] + expected: + if os == "mac": FAIL [:format="unorm8"] + expected: + if os == "mac": FAIL [:format="unorm8x2"] + expected: + if os == "mac": FAIL [:format="unorm8x4"] + expected: + if os == "mac": FAIL [:format="unorm8x4-bgra"] + expected: + if os == "mac": FAIL [cts.https.html?q=webgpu:api,validation,render_pipeline,vertex_state:vertex_attribute_offset_alignment:*] @@ -1304,84 +1392,168 @@ [cts.https.html?q=webgpu:api,validation,render_pipeline,vertex_state:vertex_shader_type_matches_attribute_format:*] + implementation-status: + if os == "mac": backlog [:format="float16"] + expected: + if os == "mac": FAIL [:format="float16x2"] + expected: + if os == "mac": FAIL [:format="float16x4"] + expected: + if os == "mac": FAIL [:format="float32"] + expected: + if os == "mac": FAIL [:format="float32x2"] + expected: + if os == "mac": FAIL [:format="float32x3"] + expected: + if os == "mac": FAIL [:format="float32x4"] + expected: + if os == "mac": FAIL [:format="sint16"] + expected: + if os == "mac": FAIL [:format="sint16x2"] + expected: + if os == "mac": FAIL [:format="sint16x4"] + expected: + if os == "mac": FAIL [:format="sint32"] + expected: + if os == "mac": FAIL [:format="sint32x2"] + expected: + if os == "mac": FAIL [:format="sint32x3"] + expected: + if os == "mac": FAIL [:format="sint32x4"] + expected: + if os == "mac": FAIL [:format="sint8"] + expected: + if os == "mac": FAIL [:format="sint8x2"] + expected: + if os == "mac": FAIL [:format="sint8x4"] + expected: + if os == "mac": FAIL [:format="snorm16"] + expected: + if os == "mac": FAIL [:format="snorm16x2"] + expected: + if os == "mac": FAIL [:format="snorm16x4"] + expected: + if os == "mac": FAIL [:format="snorm8"] + expected: + if os == "mac": FAIL [:format="snorm8x2"] + expected: + if os == "mac": FAIL [:format="snorm8x4"] + expected: + if os == "mac": FAIL [:format="uint16"] + expected: + if os == "mac": FAIL [:format="uint16x2"] + expected: + if os == "mac": FAIL [:format="uint16x4"] + expected: + if os == "mac": FAIL [:format="uint32"] + expected: + if os == "mac": FAIL [:format="uint32x2"] + expected: + if os == "mac": FAIL [:format="uint32x3"] + expected: + if os == "mac": FAIL [:format="uint32x4"] + expected: + if os == "mac": FAIL [:format="uint8"] + expected: + if os == "mac": FAIL [:format="uint8x2"] + expected: + if os == "mac": FAIL [:format="uint8x4"] + expected: + if os == "mac": FAIL [:format="unorm10-10-10-2"] + expected: + if os == "mac": FAIL [:format="unorm16"] + expected: + if os == "mac": FAIL [:format="unorm16x2"] + expected: + if os == "mac": FAIL [:format="unorm16x4"] + expected: + if os == "mac": FAIL [:format="unorm8"] + expected: + if os == "mac": FAIL [:format="unorm8x2"] + expected: + if os == "mac": FAIL [:format="unorm8x4"] + expected: + if os == "mac": FAIL [:format="unorm8x4-bgra"] + expected: + if os == "mac": FAIL diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/state/device_lost/destroy/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/api/validation/state/device_lost/destroy/cts.https.html.ini @@ -5439,37 +5439,39 @@ [:format="rgba8sint";usageType="storage";usageCopy="dst";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN] + if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="storage";usageCopy="dst";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [FAIL, TIMEOUT, NOTRUN] + if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="storage";usageCopy="none";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="storage";usageCopy="none";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="storage";usageCopy="src";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="storage";usageCopy="src";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] @@ -5487,51 +5489,60 @@ [:format="rgba8sint";usageType="texture";usageCopy="dst";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="dst";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="none";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="none";awaitLost=true] - expected: [PASS, TIMEOUT, NOTRUN] + expected: + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux": [PASS, TIMEOUT, NOTRUN] + if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="src";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="src";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="src-dest";awaitLost=false] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [TIMEOUT, NOTRUN] [:format="rgba8sint";usageType="texture";usageCopy="src-dest";awaitLost=true] expected: - if os == "win": [PASS, TIMEOUT, NOTRUN] + if os == "win": [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and not debug: [TIMEOUT, NOTRUN] @@ -5687,14 +5698,14 @@ [:format="rgba8uint";usageType="render";usageCopy="dst";awaitLost=false] expected: if os == "win" and debug: [PASS, FAIL, TIMEOUT, NOTRUN] - if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="render";usageCopy="dst";awaitLost=true] expected: if os == "win" and debug: [PASS, FAIL, TIMEOUT, NOTRUN] - if os == "win" and not debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] if os == "linux": [PASS, TIMEOUT, NOTRUN] if os == "mac": [PASS, TIMEOUT, NOTRUN] @@ -5705,16 +5716,32 @@ expected: [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="render";usageCopy="src";awaitLost=false] - expected: [PASS, TIMEOUT, NOTRUN] + expected: + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux": [PASS, TIMEOUT, NOTRUN] + if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="render";usageCopy="src";awaitLost=true] - expected: [PASS, TIMEOUT, NOTRUN] + expected: + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux": [PASS, TIMEOUT, NOTRUN] + if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="render";usageCopy="src-dest";awaitLost=false] - expected: [PASS, TIMEOUT, NOTRUN] + expected: + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux": [PASS, TIMEOUT, NOTRUN] + if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="render";usageCopy="src-dest";awaitLost=true] - expected: [PASS, TIMEOUT, NOTRUN] + expected: + if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] + if os == "win" and not debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux": [PASS, TIMEOUT, NOTRUN] + if os == "mac": [PASS, TIMEOUT, NOTRUN] [:format="rgba8uint";usageType="storage";usageCopy="dst";awaitLost=false] expected: [PASS, TIMEOUT, NOTRUN] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/execution/expression/call/builtin/atan2/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/execution/expression/call/builtin/atan2/cts.https.html.ini @@ -14,18 +14,15 @@ [cts.https.html?q=webgpu:shader,execution,expression,call,builtin,atan2:f16:*] - implementation-status: backlog + implementation-status: + if os == "win": backlog [:inputSource="const";vectorize="_undef_"] - expected: FAIL [:inputSource="const";vectorize=2] - expected: FAIL [:inputSource="const";vectorize=3] - expected: FAIL [:inputSource="const";vectorize=4] - expected: FAIL [:inputSource="storage_r";vectorize="_undef_"] @@ -55,18 +52,13 @@ [cts.https.html?q=webgpu:shader,execution,expression,call,builtin,atan2:f32:*] - implementation-status: backlog [:inputSource="const";vectorize="_undef_"] - expected: FAIL [:inputSource="const";vectorize=2] - expected: FAIL [:inputSource="const";vectorize=3] - expected: FAIL [:inputSource="const";vectorize=4] - expected: FAIL [:inputSource="storage_r";vectorize="_undef_"] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/execution/expression/call/builtin/textureSampleBias/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/execution/expression/call/builtin/textureSampleBias/cts.https.html.ini @@ -10698,7 +10698,7 @@ [:format="bc4-r-unorm";filt="nearest";mode="c"] expected: if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] - if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN] [:format="bc4-r-unorm";filt="nearest";mode="m"] @@ -10710,7 +10710,7 @@ [:format="bc4-r-unorm";filt="nearest";mode="r"] expected: if os == "win" and debug: [PASS, TIMEOUT, NOTRUN] - if os == "linux" and debug: [FAIL, TIMEOUT, NOTRUN] + if os == "linux" and debug: [PASS, TIMEOUT, NOTRUN] if os == "mac" and debug: [FAIL, TIMEOUT, NOTRUN] [:format="bc5-rg-snorm";filt="linear";mode="c"] diff --git a/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/validation/expression/call/builtin/atan2/cts.https.html.ini b/testing/web-platform/mozilla/meta/webgpu/cts/webgpu/shader/validation/expression/call/builtin/atan2/cts.https.html.ini @@ -1,9 +1,7 @@ [cts.https.html?q=webgpu:shader,validation,expression,call,builtin,atan2:invalid_argument_x:*] - implementation-status: backlog [:type="bool"] [:type="f32"] - expected: FAIL [:type="i32"] @@ -65,11 +63,9 @@ [cts.https.html?q=webgpu:shader,validation,expression,call,builtin,atan2:invalid_argument_y:*] - implementation-status: backlog [:type="bool"] [:type="f32"] - expected: FAIL [:type="i32"] @@ -136,26 +132,21 @@ expected: FAIL [:use=true] - expected: FAIL [cts.https.html?q=webgpu:shader,validation,expression,call,builtin,atan2:parameters:*] implementation-status: backlog [:test="af"] - expected: FAIL [:test="af_ai"] - expected: FAIL [:test="af_f16"] [:test="af_f32"] [:test="ai"] - expected: FAIL [:test="ai_af"] - expected: FAIL [:test="ai_f16"] @@ -221,63 +212,42 @@ [cts.https.html?q=webgpu:shader,validation,expression,call,builtin,atan2:values:*] - implementation-status: backlog [:stage="constant";type="abstract-float"] - expected: FAIL [:stage="constant";type="f16"] - expected: FAIL [:stage="constant";type="f32"] - expected: FAIL [:stage="constant";type="vec2%3Cabstract-float%3E"] - expected: FAIL [:stage="constant";type="vec2%3Cf16%3E"] - expected: FAIL [:stage="constant";type="vec2%3Cf32%3E"] - expected: FAIL [:stage="constant";type="vec3%3Cabstract-float%3E"] - expected: FAIL [:stage="constant";type="vec3%3Cf16%3E"] - expected: FAIL [:stage="constant";type="vec3%3Cf32%3E"] - expected: FAIL [:stage="constant";type="vec4%3Cabstract-float%3E"] - expected: FAIL [:stage="constant";type="vec4%3Cf16%3E"] - expected: FAIL [:stage="constant";type="vec4%3Cf32%3E"] - expected: FAIL [:stage="override";type="f16"] - expected: FAIL [:stage="override";type="f32"] - expected: FAIL [:stage="override";type="vec2%3Cf16%3E"] - expected: FAIL [:stage="override";type="vec2%3Cf32%3E"] - expected: FAIL [:stage="override";type="vec3%3Cf16%3E"] - expected: FAIL [:stage="override";type="vec3%3Cf32%3E"] - expected: FAIL [:stage="override";type="vec4%3Cf16%3E"] - expected: FAIL [:stage="override";type="vec4%3Cf32%3E"] - expected: FAIL diff --git a/third_party/rust/naga/.cargo-checksum.json b/third_party/rust/naga/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo/config.toml":"7248ed3bed246d755d7bf9e5d7842d74b5c270ba6c29ad907872b55a67707ee0","CHANGELOG.md":"e60105d413f857e37dae165f819c47491d0a595183d3c9146b259d811b98b14f","Cargo.toml":"f390c74cda757a08f168509019b05c46e0c87bae8f7bce2f658709389458c1e4","README.md":"9550cbc1a518ad0f624aabe12c342c72f670705cb4a6878c0c87d172f1dacea0","build.rs":"e9098f486e87d91710c07d40f1b32716e5debfe94a0b5e53e37075b0ee997eec","src/arena/handle.rs":"897b2b0eebe0d9ae6a65bf2e8c210c8391924da06ef4c9e2a1225ad622400b6c","src/arena/handle_set.rs":"5c2a0bcf41d85c8173ac68b2d439552e79d0c3c0fe1ff3b1e1a48f0c83a4d48f","src/arena/handlevec.rs":"999de9d55d01213789072a63ad4ae9b4635e6653984d38db8b308d42bb1e7be3","src/arena/mod.rs":"e305d0521233791e181b4b6e7de70175a6bc730811063ea066c3bd3b73d12979","src/arena/range.rs":"b783969dfe32b4937593d871aa5190d561bdd79b6f615da53cb54346e300b9e2","src/arena/unique_arena.rs":"0e2d1c372a7c40b77793dc413b8920e86459e4656775a010f32974b4ad67a7fd","src/back/continue_forward.rs":"8194d238763caa6d5601ec3af56ba39a471c39945f43152b58d582092c99aefa","src/back/dot/mod.rs":"3f63a91f4afde7bedb3163489a347ccfa4b833e1fc7a0f33ccd8817efc7d303a","src/back/glsl/features.rs":"da2c8fd44b25a03ded4a0ff2e16c5039ca77398efa7918b0af5cf055b87365e3","src/back/glsl/keywords.rs":"fee8ed132e44bace54869a7c169a1ab7ed55db1bf590b4b1bce9efa4552e1dd7","src/back/glsl/mod.rs":"86337bb3041b34d4051862665b6858afaf9c1d5bac69ce8e24b81a47e878f0d0","src/back/hlsl/conv.rs":"3e1a78203e8c4efb75986db962cec150c7b2d99f7e48b400e702233de70e8aab","src/back/hlsl/help.rs":"12ddb9d08fe64eb34b66ae2166edffce5106a04ccef0b8cc0391a6fafd676270","src/back/hlsl/keywords.rs":"f7fc06c44d2f0d620bcf1a02b699c98c32059741b771a0d1ba5645d71b2f433f","src/back/hlsl/mod.rs":"3a2983302c6a8d095923cc344de68fe0376864314381c376e8667cfabcdb9eab","src/back/hlsl/ray.rs":"259db3bc8fd5b8ec343fb8620c7cef50048cbea2b9db1f17dc8813ff848269df","src/back/hlsl/storage.rs":"5083d03b1f25fe767e45e0c507bd30424352fccd48484c081620712d3682aae8","src/back/hlsl/writer.rs":"4415d3ce654bae43ffa85d587cbb2b628cbcda387a8bf3237f1450248d423414","src/back/mod.rs":"c9a21fefbf383dca12a44cdf5201beba35384ab175eaa61da05f3a2af5310484","src/back/msl/keywords.rs":"b3e5d86d2586d553ff0fc6d91a25f0f4726c829d280a65dd2deeeb146cbbaf6d","src/back/msl/mod.rs":"b926849e99f892a3a7e5d44498f77af50d6285169461b3a2e62519236cd029f4","src/back/msl/sampler.rs":"9be8805063258b0ff6b6db2e6856d59326caa18f6f64eaf413c5abfcbd1ad341","src/back/msl/writer.rs":"51509866031f25c0e5608ce2d4d1cca5cfb943cc249a039596fddff084404830","src/back/pipeline_constants.rs":"c2244d7e47a52c01ead61b4b6c7b3d0f29263ca308aca70f213137a0938c9aa4","src/back/spv/block.rs":"7fbe28ab6679070d8960201c97890f2f69d80dc1105eae1a992a5b82f4490d35","src/back/spv/f16_polyfill.rs":"44ce07ef497dff13a9152eb9bc5936c486ef53de6d476da6b0a39396b0e6abdb","src/back/spv/helpers.rs":"6ec40b59d9f0a77e1569a2610cad1f1ca1e02bc78871ce9322e70ecdda0b3eb9","src/back/spv/image.rs":"5fb7e36ffb4236168809978ed8634a4024a910ca5a233833d89e39f9768880d3","src/back/spv/index.rs":"f4cc05768672658780f159ff8280bcf30af081af7a735338789b31f662ad1889","src/back/spv/instructions.rs":"556f1f30ae11c3e01910c354a36ba314280932e3a2928584b06eb0812a2cb81a","src/back/spv/layout.rs":"28ba27739d7c9fa4b9e363ffc112cdc39c5e8ec4236d71a7260039d1bd8321d7","src/back/spv/mod.rs":"42cd8434ce5724177491649742eb583a9e3c5c0088d96dd44ee45ca8001a86a3","src/back/spv/ray.rs":"a31fd66e9497ffd19437bdab53427705b7f28f555ab215c8f0a4c2156283413e","src/back/spv/recyclable.rs":"8ea397d4d8d3f2cd5fbc8e0be94d136c2d6e0f0e8a4b5eb567dcc1be104c9ae5","src/back/spv/selection.rs":"aea4bb4da7c0fa4e907b8f1e185433a48f2f0eb7ded97fdd3225beb3f6c1f249","src/back/spv/subgroup.rs":"68fc3e3153022a0a8bddec20ad9221820678f02921878318e571d5aa2ca13cee","src/back/spv/writer.rs":"6fd18401013facb3804d927f4f4b8e281ece1faa62ab770262cc478817449675","src/back/wgsl/mod.rs":"1b04d66e8dba609513d43431d1f0ee9a209fbfd8453862d6e8a7aa41f8910997","src/back/wgsl/polyfill/inverse/inverse_2x2_f16.wgsl":"9e7635d04724822931c805a8b35e76d6d294d447e4ea8d57b308ce45609bf736","src/back/wgsl/polyfill/inverse/inverse_2x2_f32.wgsl":"340d491abde07f93996391796db65a5f88402663eaf6b9d2d894d11cb8cf8b6d","src/back/wgsl/polyfill/inverse/inverse_3x3_f16.wgsl":"4f13a1a4b3e1b51f0f992d13c55cf854a80917554a4d13c997819fa1fe776ba4","src/back/wgsl/polyfill/inverse/inverse_3x3_f32.wgsl":"9b16d2f4b9e433c8e03a0cb46ab48508f3bf7e185ce1b4e26106c47e81a677cb","src/back/wgsl/polyfill/inverse/inverse_4x4_f16.wgsl":"86d39d1db5d03995b404950279db7f1698ad9622982aa319fdedb7532673235b","src/back/wgsl/polyfill/inverse/inverse_4x4_f32.wgsl":"dc510525ac2dce66389a8c4bf8b2f31f0dedd9e6debdbe4ffd939a0a7fc533d3","src/back/wgsl/polyfill/mod.rs":"f4ab3c9b9cdc36d16dab00d0f7f07d6e6beda0e27a36053e9b5ffeeb7ca18edc","src/back/wgsl/writer.rs":"d6ed811147b79ed74c2600bfc5485c2821dabb08b70982a4191a6a6c3d2c1a38","src/common/diagnostic_debug.rs":"8c73fe605e5b6162d0485e264287ac50c061cf581743feebbffe1474d1d3516d","src/common/diagnostic_display.rs":"46f1ff8a32179703ef0bcdb704db9f6e6e8b4eaad6cadf94577eeab3d8a16cd1","src/common/mod.rs":"289231637b08407fbe2cc976a1bab4eac4c9e66042c6618aff3af44baaff3e26","src/common/predeclared.rs":"a5f42d55f2e13d8f5a8213d4a881e9155c3994c4054d43edcf7bd7bb7c868ccf","src/common/wgsl/diagnostics.rs":"4fec985b4c5cc6dfae4dd78bd7c850adc88a1761d7b6691de0355ea49300e532","src/common/wgsl/mod.rs":"d944915ff692c96aecca67737bccc2d5d9eb68f475166a2744f29a025f4a4c93","src/common/wgsl/to_wgsl.rs":"215212963faf83c5c931c760b858c6c8b11cc582dda08f8627aefa83b6425135","src/common/wgsl/types.rs":"390323fecff390100fafcc2cb1e5cf349c7aac9da8065e9aec52a56718ab5534","src/compact/expressions.rs":"12653b34c7c7d68ce7d14a9c15e59c469fda4931425d14600fbaa99226af735f","src/compact/functions.rs":"27a0d33e5a8f02778b518c6e0db5a5d41f77a93b64eadef54b6cf0914067d7ad","src/compact/handle_set_map.rs":"b4688bff174487f2da4a1a946af07c80b6ba59f60dc84184c6a30039354209e8","src/compact/mod.rs":"7627b587f9ada7771728d0248113213ef0750e1ab9290e2a1a312a693c574568","src/compact/statements.rs":"85b2faf6a4caaebc0372e773ca3be2904db5bb0e691ac7ea845720ef0864a22b","src/compact/types.rs":"a955ce5e336afa8d26f750c14d4a6638dcee6b0b5e0fcd7c446d8f88a35d8277","src/diagnostic_filter.rs":"5e3d14a774974148b7d2918617ba3e2c3a07493e0f90485a7de9db86e05a7cd0","src/error.rs":"6a90577891fa53e2aff0538cf1e070df88346fa5813db519cf9a01ca892472b1","src/front/atomic_upgrade.rs":"86ce9f9628d92a1a09802cb534bb4310236b83f2799c921b81c687f009c589be","src/front/glsl/ast.rs":"15a4f7c56aa44529373c7aa2a266d1582b7775833de6adc6b8f5bfd54d85a669","src/front/glsl/builtins.rs":"76821d82b315ab6812e8411908885f0687ad98abfe0ea9f007e2deefed10cc0a","src/front/glsl/context.rs":"8314e1ed58b509788adbda82a8f4c7fbd2767522d0352ca1ebd11d86b4bfd10d","src/front/glsl/error.rs":"8d0d8d42e78bbacf6067dbed8f4af9f77c2fefac79f2ed90fd7d5b103b76fccc","src/front/glsl/functions.rs":"fb76ba4922898700d6b156d4f214566e60931954219d22ff2ff47689b3666613","src/front/glsl/lex.rs":"24706628b600b5ce435cef464c84196ac5d58013122a97e7b59d509cc25f85a2","src/front/glsl/mod.rs":"f4f1cce6911935b305c415afe3c15f84c7824a3bb828a5d15e6f9ae4b0316df0","src/front/glsl/offset.rs":"66bd524a2d17dc44f431430dcbbb74a771fdab43c9581e88bb1123e6cfec516b","src/front/glsl/parser.rs":"6a13b4737f53b09d5bbc0add01f8fc1b2633b7957f0318374edfe0b903939912","src/front/glsl/parser/declarations.rs":"9949649fba43636d03eaf7f7560d3bb3743b19c7204fb95859283ee84b5dd239","src/front/glsl/parser/expressions.rs":"e056fbdde3bc7c8473acbd485aecd14120d3dbefbabd813ddbc5cfedaf605889","src/front/glsl/parser/functions.rs":"302e24e06190aff555131c33f9a80b15df6a0390d6c776f888a44d5ef7df697e","src/front/glsl/parser/types.rs":"ee242048a65cd3709e16b70a3882e9296e615327480f2ad779e3d2523778181f","src/front/glsl/parser_tests.rs":"6834f0d595f4077266054e5da43e4f1b60e5c6780611ab0f530d9964cc62fad3","src/front/glsl/token.rs":"83780c0c1954ef216896c9d8a48e412b357783e00ccd4909a7a249935c742629","src/front/glsl/types.rs":"286395d82707a09d28b4c1a8bade917822478e53d8eb277ceec5fa9e71649ba2","src/front/glsl/variables.rs":"75d3e203a07befd011f5693ab8f2789e4f06821badb4974043cc4ee10bd5c6c9","src/front/interpolator.rs":"4d6c6639c01fba78ffb8d0af298094cc2d6bb33f8054dad4379fd9fe3af5a4c8","src/front/mod.rs":"fddd2be54ff44b52743ac8eb4a19e153a8a169af8e65d9061a9b9fc9857f64db","src/front/spv/convert.rs":"16b8281fc1ae75dc62a02893db2c5b6d8994166e78b3b6b8cac7a01e0da4eae2","src/front/spv/error.rs":"44cf0f9c41cc20dc858e96dbcf0766a030d47a8d2e577d1c3273be0d2d53d307","src/front/spv/function.rs":"26323687512d18c74c16e82b3aca3f5a65f1eae8a0e7e218b195f0051fe3012e","src/front/spv/image.rs":"c86d6a66c3fe94c70a647d152ab232ef810966652f1fb5796bd4f8bc56be26b8","src/front/spv/mod.rs":"fcdde0dfdeac9ed6d029ed62ffdef0287a20e6848f1fe738f7474791b3ec1b2a","src/front/spv/null.rs":"ee20287365e025e8bcc91f29df930ff8b63cb6d7f26db0b1789d54de614a7353","src/front/type_gen.rs":"111832af89a268ae3206d2ba2159b9b9d64224ed09375a29eec142725ea7fb34","src/front/wgsl/error.rs":"9f166c3589ac06bf76fe8cd753359a82e42afa0fcc78758e692ba6f047ee1a20","src/front/wgsl/index.rs":"1db1bee7074a3fe9668d2c2ba0bd5053d6443f4ea19a56e4cccf2aa2bc8a33c9","src/front/wgsl/lower/construction.rs":"24e0eb2181974651ab9d13497cceaa126ee816c38848e9dbbd88f1e7b5f5c53c","src/front/wgsl/lower/conversion.rs":"d4a66519b38caa208b011846cdc3459e8a0b6bae8027235692b30188ae88e110","src/front/wgsl/lower/mod.rs":"5473b4607ac7f89ab10cdd2bfeb59a47b52dd591ba19d85c8795d45ab4ca72de","src/front/wgsl/mod.rs":"967a045c9b5adb3904d33a273e5e284aee123f3db1bf52a0a9d83b676d568f88","src/front/wgsl/parse/ast.rs":"ca893c1cfbd76df5d4faaa43baad988c59129dd1f756b1637e7e329600c42ac5","src/front/wgsl/parse/conv.rs":"d76de215e3fea00776b5a0e8f979c074ac35a2f16892522c1a6bfe5a051c438a","src/front/wgsl/parse/directive.rs":"c96f33cef2c1d8a374fe1b3827538f7db33d6b7811a6e0914d29de80b8963257","src/front/wgsl/parse/directive/enable_extension.rs":"0618459b51fbbcf36f90d10119ed13b60f21d8b6c7c53f18b21daad4b190fa15","src/front/wgsl/parse/directive/language_extension.rs":"f82ae1c1f1d82e9e27e336b6a6975e21c7c08e5f1700f28f8d351b7f03a1621c","src/front/wgsl/parse/lexer.rs":"2194d38da1dc803ffb850202023350a07b6a3b80af68857d772c76ea49bc6344","src/front/wgsl/parse/mod.rs":"560870a843951191dcb422be6e083f16c6e0109b97fa77d225bf588124822f57","src/front/wgsl/parse/number.rs":"7af92c71031e4c4258e9d8d323f7ee99a2fd4be3b6975ab9b8b53b95431845d9","src/front/wgsl/tests.rs":"05bf78f672e54ca335ed8be59ddfb1504289ee7444258cf2d30823687a418864","src/ir/block.rs":"b562a83a4fa53002d2ca21b4553ed8e2fa77f61e687f24fd4bbd90f1597b2a9d","src/ir/mod.rs":"2933daabb5e22d023682ad5368d9c65a136000ad85f48a29104a562326a91a40","src/keywords/mod.rs":"47a6fde012bf7d1e70f0fac7762f6a8e7dca6b9bbb99e2cada773c61527cfbfe","src/keywords/wgsl.rs":"7236f0e751066712970b4f3dc9942b41d678c6a6e202c7da834f4f398e7cc657","src/lib.rs":"5d90151615cb3914bf4044a09d47e2292d1f647c26185cc49dd65c9d7c066f18","src/non_max_u32.rs":"b2d81efda0e1e5ace9e2fad990a7adf628f1dec63273b069c93d5423eb78350d","src/path_like.rs":"2740c65fc61e490b24066cdefc8ae2822650bd0c9323f83054e18005a28dfc48","src/proc/constant_evaluator.rs":"63dbd6d79061df71b922dade7ee0b01418c9d02475c149b0b9c066458b64d649","src/proc/emitter.rs":"39ac886c651e2ad33c06a676a7e4826a0e93de0af660c01e8e4b1f7406742f88","src/proc/index.rs":"17c22571251996583b724af87c7d238f584cd39104256c8e90de7b18e737bb09","src/proc/keyword_set.rs":"928414d2b79ee48735d532e03d3f0a58427c3f27a2a0c6938425749b00943784","src/proc/layouter.rs":"78a91c2c9406c0319a344cc8ec9eda33ed7812ef4a4e73e25f7709afde580381","src/proc/mod.rs":"3674ef30174a6110bad461a4208f16ed208b7347f1a8c58654b87e14558cf99c","src/proc/namer.rs":"b2318d41113b7bfdb99eda3693ca32fb3057cbd8e49db8a669ba18062a5a4992","src/proc/overloads/any_overload_set.rs":"877cd637d979abc08caa021dabb9821a79fc9109eb97024a230bcfac82830388","src/proc/overloads/constructor_set.rs":"b702f866ac1472bcc075bd0bede450388123b5899431934fd60a29865498c68b","src/proc/overloads/list.rs":"7cfbf66a3619fdd66f9acf652d56cd2a9451f7905c5d4637cdb9f77f4ef2af51","src/proc/overloads/mathfunction.rs":"d5801d64d1a6fd10e0da30a7c0ac7368954654e5f3d0b022fa806ff9a2ab61b8","src/proc/overloads/mod.rs":"0e96479cbd0ec9fa8200a5e88c16a22ee7ed2021ecf6f80a7e4ded69cad5239f","src/proc/overloads/one_bits_iter.rs":"6b98769fdec777d311248084f13958c5cca44659d0928603ece8618387ea58b2","src/proc/overloads/regular.rs":"73d64fab79019d589cb0595d0ef606fd6af732c42a418c60c81da4c96e113c89","src/proc/overloads/rule.rs":"b7f87d5ca0cffdaa8ee0db0110918f5a726359fd8a72bc638d8ce27a4b0ae3b2","src/proc/overloads/scalar_set.rs":"3729bc754dbf29a2337379ecb46568fdc3149a48074a354244da91e3d9cb5cef","src/proc/overloads/utils.rs":"4b5e02f20611bd24c6849e1f2c01aad4b271388407e8eb866d5a34983538ef8f","src/proc/terminator.rs":"61df2289408be24f69b6c23da469ca3f63f913568f8c314427c3571b826632dd","src/proc/type_methods.rs":"fef829acb2da08a22a2e30dc356e7a8b9149ef13582525bea0143c687a1c57dd","src/proc/typifier.rs":"a31a97013838e43d31cef69b032680187ac709e13db0bf8fc85f4e8e11f236cf","src/racy_lock.rs":"6c541795172660e02bac86c3808cf7346b4791910febc0d289bf93d36271d416","src/span.rs":"38b673c3c75b2e04948530cded77f5f166866ee917ae2f13feba768a2525ec30","src/valid/analyzer.rs":"9e0479bee5d2ac15704f69d8852400cd1bcd35bc01c056cb9a510db6dec63a39","src/valid/compose.rs":"46eeed8c4d5b66fc043ddb701074bd864a9fdd24e38b88e282046230acefb747","src/valid/expression.rs":"f8d9e3e20d21ddb9ade2e793d590631bcf4e7c135804a0130302d57212521f6f","src/valid/function.rs":"e97ddecd0369f192fd25c59aeeef3bdd04f86858f5ed625dc384c2d00030ebbc","src/valid/handles.rs":"59f96f672f57e253006f330a3b9a540564dfb462a543e5cad6d20231de29538f","src/valid/interface.rs":"d6bddc8c722ed6e36371bc7796922a524f443f870a06b8f874f2aa49bde682d3","src/valid/mod.rs":"83a51f1e5d30dc1b3118218e21d1ac87d4c16ebb962fd71d50534d258fef8d7d","src/valid/type.rs":"65d2c02000e8038d9adab6ea94741fea61844d0626d7fa4389c54dcaa594704b"},"package":null} -\ No newline at end of file +{"files":{".cargo/config.toml":"7248ed3bed246d755d7bf9e5d7842d74b5c270ba6c29ad907872b55a67707ee0","CHANGELOG.md":"e60105d413f857e37dae165f819c47491d0a595183d3c9146b259d811b98b14f","Cargo.toml":"ef3bd3969b5ceecb78a246e2b87f61856257697b5b9fe25b95749567737ebe5c","README.md":"9550cbc1a518ad0f624aabe12c342c72f670705cb4a6878c0c87d172f1dacea0","build.rs":"e9098f486e87d91710c07d40f1b32716e5debfe94a0b5e53e37075b0ee997eec","src/arena/handle.rs":"897b2b0eebe0d9ae6a65bf2e8c210c8391924da06ef4c9e2a1225ad622400b6c","src/arena/handle_set.rs":"5c2a0bcf41d85c8173ac68b2d439552e79d0c3c0fe1ff3b1e1a48f0c83a4d48f","src/arena/handlevec.rs":"999de9d55d01213789072a63ad4ae9b4635e6653984d38db8b308d42bb1e7be3","src/arena/mod.rs":"e305d0521233791e181b4b6e7de70175a6bc730811063ea066c3bd3b73d12979","src/arena/range.rs":"b783969dfe32b4937593d871aa5190d561bdd79b6f615da53cb54346e300b9e2","src/arena/unique_arena.rs":"0e2d1c372a7c40b77793dc413b8920e86459e4656775a010f32974b4ad67a7fd","src/back/continue_forward.rs":"8194d238763caa6d5601ec3af56ba39a471c39945f43152b58d582092c99aefa","src/back/dot/mod.rs":"3f63a91f4afde7bedb3163489a347ccfa4b833e1fc7a0f33ccd8817efc7d303a","src/back/glsl/features.rs":"da2c8fd44b25a03ded4a0ff2e16c5039ca77398efa7918b0af5cf055b87365e3","src/back/glsl/keywords.rs":"fee8ed132e44bace54869a7c169a1ab7ed55db1bf590b4b1bce9efa4552e1dd7","src/back/glsl/mod.rs":"86337bb3041b34d4051862665b6858afaf9c1d5bac69ce8e24b81a47e878f0d0","src/back/hlsl/conv.rs":"3e1a78203e8c4efb75986db962cec150c7b2d99f7e48b400e702233de70e8aab","src/back/hlsl/help.rs":"12ddb9d08fe64eb34b66ae2166edffce5106a04ccef0b8cc0391a6fafd676270","src/back/hlsl/keywords.rs":"f7fc06c44d2f0d620bcf1a02b699c98c32059741b771a0d1ba5645d71b2f433f","src/back/hlsl/mod.rs":"e83d54a5741f6f5c89d5e8ac56015021ceb9077262c3b9c47f0bf1a7e35dbab5","src/back/hlsl/ray.rs":"259db3bc8fd5b8ec343fb8620c7cef50048cbea2b9db1f17dc8813ff848269df","src/back/hlsl/storage.rs":"5083d03b1f25fe767e45e0c507bd30424352fccd48484c081620712d3682aae8","src/back/hlsl/writer.rs":"4415d3ce654bae43ffa85d587cbb2b628cbcda387a8bf3237f1450248d423414","src/back/mod.rs":"c9a21fefbf383dca12a44cdf5201beba35384ab175eaa61da05f3a2af5310484","src/back/msl/keywords.rs":"b3e5d86d2586d553ff0fc6d91a25f0f4726c829d280a65dd2deeeb146cbbaf6d","src/back/msl/mod.rs":"f9d05aadd4d6cb6fea165c7e0b31c910b63d8102de60edfe283f8f56b8d4197f","src/back/msl/sampler.rs":"9be8805063258b0ff6b6db2e6856d59326caa18f6f64eaf413c5abfcbd1ad341","src/back/msl/writer.rs":"428b128d841dc62286da91105b282984f69a72b562516ceba9ef6f9b267ce91d","src/back/pipeline_constants.rs":"c2244d7e47a52c01ead61b4b6c7b3d0f29263ca308aca70f213137a0938c9aa4","src/back/spv/block.rs":"7fbe28ab6679070d8960201c97890f2f69d80dc1105eae1a992a5b82f4490d35","src/back/spv/f16_polyfill.rs":"44ce07ef497dff13a9152eb9bc5936c486ef53de6d476da6b0a39396b0e6abdb","src/back/spv/helpers.rs":"6ec40b59d9f0a77e1569a2610cad1f1ca1e02bc78871ce9322e70ecdda0b3eb9","src/back/spv/image.rs":"5fb7e36ffb4236168809978ed8634a4024a910ca5a233833d89e39f9768880d3","src/back/spv/index.rs":"f4cc05768672658780f159ff8280bcf30af081af7a735338789b31f662ad1889","src/back/spv/instructions.rs":"556f1f30ae11c3e01910c354a36ba314280932e3a2928584b06eb0812a2cb81a","src/back/spv/layout.rs":"28ba27739d7c9fa4b9e363ffc112cdc39c5e8ec4236d71a7260039d1bd8321d7","src/back/spv/mod.rs":"86b21da8ec035ab9b27d73b943bb7e7978e8c3539402b5c3d2160e9e171dc81d","src/back/spv/ray.rs":"a31fd66e9497ffd19437bdab53427705b7f28f555ab215c8f0a4c2156283413e","src/back/spv/recyclable.rs":"8ea397d4d8d3f2cd5fbc8e0be94d136c2d6e0f0e8a4b5eb567dcc1be104c9ae5","src/back/spv/selection.rs":"aea4bb4da7c0fa4e907b8f1e185433a48f2f0eb7ded97fdd3225beb3f6c1f249","src/back/spv/subgroup.rs":"68fc3e3153022a0a8bddec20ad9221820678f02921878318e571d5aa2ca13cee","src/back/spv/writer.rs":"e6faaa9ebad5b1a7640a83ab473fda8dacf292ff22844cba5355f3901ef00c83","src/back/wgsl/mod.rs":"1b04d66e8dba609513d43431d1f0ee9a209fbfd8453862d6e8a7aa41f8910997","src/back/wgsl/polyfill/inverse/inverse_2x2_f16.wgsl":"9e7635d04724822931c805a8b35e76d6d294d447e4ea8d57b308ce45609bf736","src/back/wgsl/polyfill/inverse/inverse_2x2_f32.wgsl":"340d491abde07f93996391796db65a5f88402663eaf6b9d2d894d11cb8cf8b6d","src/back/wgsl/polyfill/inverse/inverse_3x3_f16.wgsl":"4f13a1a4b3e1b51f0f992d13c55cf854a80917554a4d13c997819fa1fe776ba4","src/back/wgsl/polyfill/inverse/inverse_3x3_f32.wgsl":"9b16d2f4b9e433c8e03a0cb46ab48508f3bf7e185ce1b4e26106c47e81a677cb","src/back/wgsl/polyfill/inverse/inverse_4x4_f16.wgsl":"86d39d1db5d03995b404950279db7f1698ad9622982aa319fdedb7532673235b","src/back/wgsl/polyfill/inverse/inverse_4x4_f32.wgsl":"dc510525ac2dce66389a8c4bf8b2f31f0dedd9e6debdbe4ffd939a0a7fc533d3","src/back/wgsl/polyfill/mod.rs":"f4ab3c9b9cdc36d16dab00d0f7f07d6e6beda0e27a36053e9b5ffeeb7ca18edc","src/back/wgsl/writer.rs":"d6ed811147b79ed74c2600bfc5485c2821dabb08b70982a4191a6a6c3d2c1a38","src/common/diagnostic_debug.rs":"8c73fe605e5b6162d0485e264287ac50c061cf581743feebbffe1474d1d3516d","src/common/diagnostic_display.rs":"46f1ff8a32179703ef0bcdb704db9f6e6e8b4eaad6cadf94577eeab3d8a16cd1","src/common/mod.rs":"289231637b08407fbe2cc976a1bab4eac4c9e66042c6618aff3af44baaff3e26","src/common/predeclared.rs":"a5f42d55f2e13d8f5a8213d4a881e9155c3994c4054d43edcf7bd7bb7c868ccf","src/common/wgsl/diagnostics.rs":"4fec985b4c5cc6dfae4dd78bd7c850adc88a1761d7b6691de0355ea49300e532","src/common/wgsl/mod.rs":"d944915ff692c96aecca67737bccc2d5d9eb68f475166a2744f29a025f4a4c93","src/common/wgsl/to_wgsl.rs":"215212963faf83c5c931c760b858c6c8b11cc582dda08f8627aefa83b6425135","src/common/wgsl/types.rs":"390323fecff390100fafcc2cb1e5cf349c7aac9da8065e9aec52a56718ab5534","src/compact/expressions.rs":"12653b34c7c7d68ce7d14a9c15e59c469fda4931425d14600fbaa99226af735f","src/compact/functions.rs":"27a0d33e5a8f02778b518c6e0db5a5d41f77a93b64eadef54b6cf0914067d7ad","src/compact/handle_set_map.rs":"b4688bff174487f2da4a1a946af07c80b6ba59f60dc84184c6a30039354209e8","src/compact/mod.rs":"7627b587f9ada7771728d0248113213ef0750e1ab9290e2a1a312a693c574568","src/compact/statements.rs":"85b2faf6a4caaebc0372e773ca3be2904db5bb0e691ac7ea845720ef0864a22b","src/compact/types.rs":"a955ce5e336afa8d26f750c14d4a6638dcee6b0b5e0fcd7c446d8f88a35d8277","src/diagnostic_filter.rs":"5e3d14a774974148b7d2918617ba3e2c3a07493e0f90485a7de9db86e05a7cd0","src/error.rs":"46180b139b60cca1e46a8848f9eecc5cab8220a022e4c6f8ce297d1d968e87e7","src/front/atomic_upgrade.rs":"86ce9f9628d92a1a09802cb534bb4310236b83f2799c921b81c687f009c589be","src/front/glsl/ast.rs":"15a4f7c56aa44529373c7aa2a266d1582b7775833de6adc6b8f5bfd54d85a669","src/front/glsl/builtins.rs":"76821d82b315ab6812e8411908885f0687ad98abfe0ea9f007e2deefed10cc0a","src/front/glsl/context.rs":"8314e1ed58b509788adbda82a8f4c7fbd2767522d0352ca1ebd11d86b4bfd10d","src/front/glsl/error.rs":"f445297e0357919e2345ae15f2d23c58d36a64c9a666f1cf1b09cbcfd6e4627a","src/front/glsl/functions.rs":"fb76ba4922898700d6b156d4f214566e60931954219d22ff2ff47689b3666613","src/front/glsl/lex.rs":"24706628b600b5ce435cef464c84196ac5d58013122a97e7b59d509cc25f85a2","src/front/glsl/mod.rs":"f4f1cce6911935b305c415afe3c15f84c7824a3bb828a5d15e6f9ae4b0316df0","src/front/glsl/offset.rs":"66bd524a2d17dc44f431430dcbbb74a771fdab43c9581e88bb1123e6cfec516b","src/front/glsl/parser.rs":"6a13b4737f53b09d5bbc0add01f8fc1b2633b7957f0318374edfe0b903939912","src/front/glsl/parser/declarations.rs":"9949649fba43636d03eaf7f7560d3bb3743b19c7204fb95859283ee84b5dd239","src/front/glsl/parser/expressions.rs":"e056fbdde3bc7c8473acbd485aecd14120d3dbefbabd813ddbc5cfedaf605889","src/front/glsl/parser/functions.rs":"302e24e06190aff555131c33f9a80b15df6a0390d6c776f888a44d5ef7df697e","src/front/glsl/parser/types.rs":"ee242048a65cd3709e16b70a3882e9296e615327480f2ad779e3d2523778181f","src/front/glsl/parser_tests.rs":"6834f0d595f4077266054e5da43e4f1b60e5c6780611ab0f530d9964cc62fad3","src/front/glsl/token.rs":"83780c0c1954ef216896c9d8a48e412b357783e00ccd4909a7a249935c742629","src/front/glsl/types.rs":"286395d82707a09d28b4c1a8bade917822478e53d8eb277ceec5fa9e71649ba2","src/front/glsl/variables.rs":"75d3e203a07befd011f5693ab8f2789e4f06821badb4974043cc4ee10bd5c6c9","src/front/interpolator.rs":"4d6c6639c01fba78ffb8d0af298094cc2d6bb33f8054dad4379fd9fe3af5a4c8","src/front/mod.rs":"fddd2be54ff44b52743ac8eb4a19e153a8a169af8e65d9061a9b9fc9857f64db","src/front/spv/convert.rs":"16b8281fc1ae75dc62a02893db2c5b6d8994166e78b3b6b8cac7a01e0da4eae2","src/front/spv/error.rs":"44cf0f9c41cc20dc858e96dbcf0766a030d47a8d2e577d1c3273be0d2d53d307","src/front/spv/function.rs":"26323687512d18c74c16e82b3aca3f5a65f1eae8a0e7e218b195f0051fe3012e","src/front/spv/image.rs":"c39ffdb19a19861cec009de39431a879be99bdd4d9d08c0ecdef397c2f3f6fa5","src/front/spv/mod.rs":"5e54af3cc50ed33bc573c5fb758b68be5a077d57f0f059899be2b67b30ad0313","src/front/spv/null.rs":"ee20287365e025e8bcc91f29df930ff8b63cb6d7f26db0b1789d54de614a7353","src/front/type_gen.rs":"111832af89a268ae3206d2ba2159b9b9d64224ed09375a29eec142725ea7fb34","src/front/wgsl/error.rs":"60c7113a98f5642dc31ff23d20d8f533ee3fa80e88246a6e277615e7b9efa0f1","src/front/wgsl/index.rs":"1db1bee7074a3fe9668d2c2ba0bd5053d6443f4ea19a56e4cccf2aa2bc8a33c9","src/front/wgsl/lower/construction.rs":"24e0eb2181974651ab9d13497cceaa126ee816c38848e9dbbd88f1e7b5f5c53c","src/front/wgsl/lower/conversion.rs":"d4a66519b38caa208b011846cdc3459e8a0b6bae8027235692b30188ae88e110","src/front/wgsl/lower/mod.rs":"5473b4607ac7f89ab10cdd2bfeb59a47b52dd591ba19d85c8795d45ab4ca72de","src/front/wgsl/mod.rs":"967a045c9b5adb3904d33a273e5e284aee123f3db1bf52a0a9d83b676d568f88","src/front/wgsl/parse/ast.rs":"ca893c1cfbd76df5d4faaa43baad988c59129dd1f756b1637e7e329600c42ac5","src/front/wgsl/parse/conv.rs":"d76de215e3fea00776b5a0e8f979c074ac35a2f16892522c1a6bfe5a051c438a","src/front/wgsl/parse/directive.rs":"c96f33cef2c1d8a374fe1b3827538f7db33d6b7811a6e0914d29de80b8963257","src/front/wgsl/parse/directive/enable_extension.rs":"0618459b51fbbcf36f90d10119ed13b60f21d8b6c7c53f18b21daad4b190fa15","src/front/wgsl/parse/directive/language_extension.rs":"f82ae1c1f1d82e9e27e336b6a6975e21c7c08e5f1700f28f8d351b7f03a1621c","src/front/wgsl/parse/lexer.rs":"2194d38da1dc803ffb850202023350a07b6a3b80af68857d772c76ea49bc6344","src/front/wgsl/parse/mod.rs":"560870a843951191dcb422be6e083f16c6e0109b97fa77d225bf588124822f57","src/front/wgsl/parse/number.rs":"7af92c71031e4c4258e9d8d323f7ee99a2fd4be3b6975ab9b8b53b95431845d9","src/front/wgsl/tests.rs":"05bf78f672e54ca335ed8be59ddfb1504289ee7444258cf2d30823687a418864","src/ir/block.rs":"b562a83a4fa53002d2ca21b4553ed8e2fa77f61e687f24fd4bbd90f1597b2a9d","src/ir/mod.rs":"2933daabb5e22d023682ad5368d9c65a136000ad85f48a29104a562326a91a40","src/keywords/mod.rs":"47a6fde012bf7d1e70f0fac7762f6a8e7dca6b9bbb99e2cada773c61527cfbfe","src/keywords/wgsl.rs":"7236f0e751066712970b4f3dc9942b41d678c6a6e202c7da834f4f398e7cc657","src/lib.rs":"5d90151615cb3914bf4044a09d47e2292d1f647c26185cc49dd65c9d7c066f18","src/non_max_u32.rs":"b2d81efda0e1e5ace9e2fad990a7adf628f1dec63273b069c93d5423eb78350d","src/path_like.rs":"2740c65fc61e490b24066cdefc8ae2822650bd0c9323f83054e18005a28dfc48","src/proc/constant_evaluator.rs":"7a39635e81f2fd2e56acd8b845d50667dbfc3b107c4529b3feed283001b1d1fd","src/proc/emitter.rs":"39ac886c651e2ad33c06a676a7e4826a0e93de0af660c01e8e4b1f7406742f88","src/proc/index.rs":"17c22571251996583b724af87c7d238f584cd39104256c8e90de7b18e737bb09","src/proc/keyword_set.rs":"928414d2b79ee48735d532e03d3f0a58427c3f27a2a0c6938425749b00943784","src/proc/layouter.rs":"78a91c2c9406c0319a344cc8ec9eda33ed7812ef4a4e73e25f7709afde580381","src/proc/mod.rs":"3674ef30174a6110bad461a4208f16ed208b7347f1a8c58654b87e14558cf99c","src/proc/namer.rs":"b2318d41113b7bfdb99eda3693ca32fb3057cbd8e49db8a669ba18062a5a4992","src/proc/overloads/any_overload_set.rs":"877cd637d979abc08caa021dabb9821a79fc9109eb97024a230bcfac82830388","src/proc/overloads/constructor_set.rs":"b702f866ac1472bcc075bd0bede450388123b5899431934fd60a29865498c68b","src/proc/overloads/list.rs":"7cfbf66a3619fdd66f9acf652d56cd2a9451f7905c5d4637cdb9f77f4ef2af51","src/proc/overloads/mathfunction.rs":"d5801d64d1a6fd10e0da30a7c0ac7368954654e5f3d0b022fa806ff9a2ab61b8","src/proc/overloads/mod.rs":"0e96479cbd0ec9fa8200a5e88c16a22ee7ed2021ecf6f80a7e4ded69cad5239f","src/proc/overloads/one_bits_iter.rs":"6b98769fdec777d311248084f13958c5cca44659d0928603ece8618387ea58b2","src/proc/overloads/regular.rs":"73d64fab79019d589cb0595d0ef606fd6af732c42a418c60c81da4c96e113c89","src/proc/overloads/rule.rs":"b7f87d5ca0cffdaa8ee0db0110918f5a726359fd8a72bc638d8ce27a4b0ae3b2","src/proc/overloads/scalar_set.rs":"3729bc754dbf29a2337379ecb46568fdc3149a48074a354244da91e3d9cb5cef","src/proc/overloads/utils.rs":"4b5e02f20611bd24c6849e1f2c01aad4b271388407e8eb866d5a34983538ef8f","src/proc/terminator.rs":"61df2289408be24f69b6c23da469ca3f63f913568f8c314427c3571b826632dd","src/proc/type_methods.rs":"fef829acb2da08a22a2e30dc356e7a8b9149ef13582525bea0143c687a1c57dd","src/proc/typifier.rs":"a31a97013838e43d31cef69b032680187ac709e13db0bf8fc85f4e8e11f236cf","src/racy_lock.rs":"6c541795172660e02bac86c3808cf7346b4791910febc0d289bf93d36271d416","src/span.rs":"38b673c3c75b2e04948530cded77f5f166866ee917ae2f13feba768a2525ec30","src/valid/analyzer.rs":"9e0479bee5d2ac15704f69d8852400cd1bcd35bc01c056cb9a510db6dec63a39","src/valid/compose.rs":"46eeed8c4d5b66fc043ddb701074bd864a9fdd24e38b88e282046230acefb747","src/valid/expression.rs":"f8d9e3e20d21ddb9ade2e793d590631bcf4e7c135804a0130302d57212521f6f","src/valid/function.rs":"e97ddecd0369f192fd25c59aeeef3bdd04f86858f5ed625dc384c2d00030ebbc","src/valid/handles.rs":"59f96f672f57e253006f330a3b9a540564dfb462a543e5cad6d20231de29538f","src/valid/interface.rs":"d6bddc8c722ed6e36371bc7796922a524f443f870a06b8f874f2aa49bde682d3","src/valid/mod.rs":"83a51f1e5d30dc1b3118218e21d1ac87d4c16ebb962fd71d50534d258fef8d7d","src/valid/type.rs":"65d2c02000e8038d9adab6ea94741fea61844d0626d7fa4389c54dcaa594704b"},"package":null} +\ No newline at end of file diff --git a/third_party/rust/naga/Cargo.toml b/third_party/rust/naga/Cargo.toml @@ -119,7 +119,7 @@ features = ["num-traits"] default-features = false [dependencies.hashbrown] -version = "0.15" +version = "0.16" features = [ "default-hasher", "inline-more", @@ -131,7 +131,7 @@ version = "0.2" optional = true [dependencies.indexmap] -version = "2.7" +version = "2.8" default-features = false [dependencies.libm] @@ -195,7 +195,7 @@ version = "0.11" default-features = false [dev-dependencies.hashbrown] -version = "0.15" +version = "0.16" features = [ "default-hasher", "inline-more", @@ -214,7 +214,7 @@ version = "26.0.0" path = "../naga-test" [dev-dependencies.ron] -version = "0.10" +version = "0.11" [dev-dependencies.rspirv] version = "0.12" @@ -231,7 +231,7 @@ default-features = false version = "0.3" [dev-dependencies.strum] -version = "0.27" +version = "0.27.1" features = ["derive"] default-features = false diff --git a/third_party/rust/naga/src/back/hlsl/mod.rs b/third_party/rust/naga/src/back/hlsl/mod.rs @@ -283,7 +283,8 @@ impl crate::ShaderStage { Self::Vertex => "vs", Self::Fragment => "ps", Self::Compute => "cs", - Self::Task | Self::Mesh => unreachable!(), + Self::Task => "as", + Self::Mesh => "ms", } } } diff --git a/third_party/rust/naga/src/back/msl/mod.rs b/third_party/rust/naga/src/back/msl/mod.rs @@ -119,9 +119,8 @@ pub struct BindTarget { pub mutable: bool, } -#[cfg(any(feature = "serialize", feature = "deserialize"))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize))] -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +#[cfg(feature = "deserialize")] +#[derive(serde::Deserialize)] struct BindingMapSerialization { resource_binding: crate::ResourceBinding, bind_target: BindTarget, @@ -418,6 +417,17 @@ pub enum VertexFormat { Unorm8x4Bgra = 44, } +/// Defines how to advance the data in vertex buffers. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub enum VertexBufferStepMode { + Constant, + #[default] + ByVertex, + ByInstance, +} + /// A mapping of vertex buffers and their attributes to shader /// locations. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -446,9 +456,8 @@ pub struct VertexBufferMapping { pub id: u32, /// Size of the structure in bytes pub stride: u32, - /// True if the buffer is indexed by vertex, false if indexed - /// by instance. - pub indexed_by_vertex: bool, + /// Vertex buffer step mode + pub step_mode: VertexBufferStepMode, /// Vec of the attributes within the structure pub attributes: Vec<AttributeMapping>, } diff --git a/third_party/rust/naga/src/back/msl/writer.rs b/third_party/rust/naga/src/back/msl/writer.rs @@ -6359,7 +6359,7 @@ template <typename A> struct VertexBufferMappingResolved<'a> { id: u32, stride: u32, - indexed_by_vertex: bool, + step_mode: back::msl::VertexBufferStepMode, ty_name: String, param_name: String, elem_name: String, @@ -6395,10 +6395,14 @@ template <typename A> "Vertex pulling requires a non-zero buffer stride." ); - if vbm.indexed_by_vertex { - needs_vertex_id = true; - } else { - needs_instance_id = true; + match vbm.step_mode { + back::msl::VertexBufferStepMode::Constant => {} + back::msl::VertexBufferStepMode::ByVertex => { + needs_vertex_id = true; + } + back::msl::VertexBufferStepMode::ByInstance => { + needs_instance_id = true; + } } let buffer_ty = self.namer.call(format!("vb_{buffer_id}_type").as_str()); @@ -6408,7 +6412,7 @@ template <typename A> vbm_resolved.push(VertexBufferMappingResolved { id: buffer_id, stride: buffer_stride, - indexed_by_vertex: vbm.indexed_by_vertex, + step_mode: vbm.step_mode, ty_name: buffer_ty, param_name: buffer_param, elem_name: buffer_elem, @@ -7199,8 +7203,6 @@ template <typename A> } if do_vertex_pulling { - assert!(needs_vertex_id || needs_instance_id); - let mut separator = if is_first_argument { is_first_argument = false; ' ' @@ -7278,16 +7280,22 @@ template <typename A> let idx = &vbm.id; let stride = &vbm.stride; - let index_name = if vbm.indexed_by_vertex { - if let Some(ref name) = v_existing_id { - name - } else { - &v_id + let index_name = match vbm.step_mode { + back::msl::VertexBufferStepMode::Constant => "0", + back::msl::VertexBufferStepMode::ByVertex => { + if let Some(ref name) = v_existing_id { + name + } else { + &v_id + } + } + back::msl::VertexBufferStepMode::ByInstance => { + if let Some(ref name) = i_existing_id { + name + } else { + &i_id + } } - } else if let Some(ref name) = i_existing_id { - name - } else { - &i_id }; write!( self.out, diff --git a/third_party/rust/naga/src/back/spv/mod.rs b/third_party/rust/naga/src/back/spv/mod.rs @@ -79,6 +79,8 @@ pub enum Error { Override, #[error(transparent)] ResolveArraySizeError(#[from] crate::proc::ResolveArraySizeError), + #[error("mapping of {0:?} is missing")] + MissingBinding(crate::ResourceBinding), } #[derive(Default)] @@ -760,6 +762,7 @@ pub struct Writer { constant_ids: HandleVec<crate::Expression, Word>, cached_constants: crate::FastHashMap<CachedConstant, Word>, global_variables: HandleVec<crate::GlobalVariable, GlobalVariable>, + fake_missing_bindings: bool, binding_map: BindingMap, // Cached expressions are only meaningful within a BlockContext, but we @@ -811,10 +814,12 @@ bitflags::bitflags! { } } -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub struct BindingInfo { + pub descriptor_set: u32, + pub binding: u32, /// If the binding is an unsized binding array, this overrides the size. pub binding_array_size: Option<u32>, } @@ -839,6 +844,10 @@ pub struct Options<'a> { /// Configuration flags for the writer. pub flags: WriterFlags, + /// Don't panic on missing bindings. Instead use fake values for `Binding` + /// and `DescriptorSet` decorations. This may result in invalid SPIR-V. + pub fake_missing_bindings: bool, + /// Map of resources to information about the binding. pub binding_map: BindingMap, @@ -877,6 +886,7 @@ impl Default for Options<'_> { Options { lang_version: (1, 0), flags, + fake_missing_bindings: true, binding_map: BindingMap::default(), capabilities: None, bounds_check_policies: BoundsCheckPolicies::default(), diff --git a/third_party/rust/naga/src/back/spv/writer.rs b/third_party/rust/naga/src/back/spv/writer.rs @@ -87,6 +87,7 @@ impl Writer { constant_ids: HandleVec::new(), cached_constants: crate::FastHashMap::default(), global_variables: HandleVec::new(), + fake_missing_bindings: options.fake_missing_bindings, binding_map: options.binding_map.clone(), saved_cached: CachedExpressions::default(), gl450_ext_inst_id, @@ -149,6 +150,7 @@ impl Writer { force_loop_bounding: self.force_loop_bounding, use_storage_input_output_16: self.use_storage_input_output_16, capabilities_available: take(&mut self.capabilities_available), + fake_missing_bindings: self.fake_missing_bindings, binding_map: take(&mut self.binding_map), // Initialized afresh: @@ -469,6 +471,26 @@ impl Writer { }) } + /// Resolve the [`BindingInfo`] for a [`crate::ResourceBinding`] from the + /// provided [`Writer::binding_map`]. + /// + /// If the specified resource is not present in the binding map this will + /// return an error, unless [`Writer::fake_missing_bindings`] is set. + fn resolve_resource_binding( + &self, + res_binding: &crate::ResourceBinding, + ) -> Result<BindingInfo, Error> { + match self.binding_map.get(res_binding) { + Some(target) => Ok(*target), + None if self.fake_missing_bindings => Ok(BindingInfo { + descriptor_set: res_binding.group, + binding: res_binding.binding, + binding_array_size: None, + }), + None => Err(Error::MissingBinding(*res_binding)), + } + } + /// Emits code for any wrapper functions required by the expressions in ir_function. /// The IDs of any emitted functions will be stored in [`Self::wrapped_functions`]. fn write_wrapped_functions( @@ -2241,13 +2263,11 @@ impl Writer { // and it is failing on 0. let mut substitute_inner_type_lookup = None; if let Some(ref res_binding) = global_variable.binding { - self.decorate(id, Decoration::DescriptorSet, &[res_binding.group]); - self.decorate(id, Decoration::Binding, &[res_binding.binding]); + let bind_target = self.resolve_resource_binding(res_binding)?; + self.decorate(id, Decoration::DescriptorSet, &[bind_target.descriptor_set]); + self.decorate(id, Decoration::Binding, &[bind_target.binding]); - if let Some(&BindingInfo { - binding_array_size: Some(remapped_binding_array_size), - }) = self.binding_map.get(res_binding) - { + if let Some(remapped_binding_array_size) = bind_target.binding_array_size { if let crate::TypeInner::BindingArray { base, .. } = ir_module.types[global_variable.ty].inner { diff --git a/third_party/rust/naga/src/error.rs b/third_party/rust/naga/src/error.rs @@ -134,7 +134,7 @@ where E: Error + 'static, { fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.inner) + self.inner.source() } } diff --git a/third_party/rust/naga/src/front/glsl/error.rs b/third_party/rust/naga/src/front/glsl/error.rs @@ -198,11 +198,7 @@ impl core::fmt::Display for ParseErrors { } } -impl core::error::Error for ParseErrors { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - None - } -} +impl core::error::Error for ParseErrors {} impl From<Vec<Error>> for ParseErrors { fn from(errors: Vec<Error>) -> Self { diff --git a/third_party/rust/naga/src/front/spv/image.rs b/third_party/rust/naga/src/front/spv/image.rs @@ -48,6 +48,8 @@ pub struct SamplingOptions { pub project: bool, /// Depth comparison sampling with a reference value. pub compare: bool, + /// Gather sampling: Operates on four samples of one channel. + pub gather: bool, } enum ExtraCoordinate { @@ -500,10 +502,10 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> { let result_id = self.next()?; let sampled_image_id = self.next()?; let coordinate_id = self.next()?; - let dref_id = if options.compare { - Some(self.next()?) - } else { - None + let (component_id, dref_id) = match (options.gather, options.compare) { + (true, false) => (Some(self.next()?), None), + (_, true) => (None, Some(self.next()?)), + (_, _) => (None, None), }; let span = self.span_from_with_op(start); @@ -629,6 +631,58 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> { self.get_expr_handle(coordinate_id, coord_lexp, ctx, emitter, block, body_idx); let coord_type_handle = self.lookup_type.lookup(coord_lexp.type_id)?.handle; + let gather = match (options.gather, component_id) { + (true, Some(component_id)) => { + let component_lexp = self.lookup_expression.lookup(component_id)?; + + let component_value = match ctx.expressions[component_lexp.handle] { + // VUID-StandaloneSpirv-OpImageGather-04664: + // The “Component” operand of OpImageGather, and OpImageSparseGather must be the + // <id> of a constant instruction. + crate::Expression::Constant(const_handle) => { + let constant = &ctx.module.constants[const_handle]; + match ctx.module.global_expressions[constant.init] { + // SPIR-V specification: "It must be a 32-bit integer type scalar." + crate::Expression::Literal(crate::Literal::U32(value)) => value, + crate::Expression::Literal(crate::Literal::I32(value)) => value as u32, + _ => { + log::error!( + "Image gather component constant must be a 32-bit integer literal" + ); + return Err(Error::InvalidOperand); + } + } + } + _ => { + log::error!("Image gather component must be a constant"); + return Err(Error::InvalidOperand); + } + }; + + debug_assert_eq!(level, crate::SampleLevel::Auto); + level = crate::SampleLevel::Zero; + + // SPIR-V specification: "Behavior is undefined if its value is not 0, 1, 2 or 3." + match component_value { + 0 => Some(crate::SwizzleComponent::X), + 1 => Some(crate::SwizzleComponent::Y), + 2 => Some(crate::SwizzleComponent::Z), + 3 => Some(crate::SwizzleComponent::W), + other => { + log::error!("Invalid gather component operand: {other}"); + return Err(Error::InvalidOperand); + } + } + } + (true, None) => { + debug_assert_eq!(level, crate::SampleLevel::Auto); + level = crate::SampleLevel::Zero; + + Some(crate::SwizzleComponent::X) + } + (_, _) => None, + }; + let sampling_bit = if options.compare { SamplingFlags::COMPARISON } else { @@ -745,7 +799,7 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> { let expr = crate::Expression::ImageSample { image: si_lexp.image, sampler: si_lexp.sampler, - gather: None, //TODO + gather, coordinate, array_index, offset, diff --git a/third_party/rust/naga/src/front/spv/mod.rs b/third_party/rust/naga/src/front/spv/mod.rs @@ -82,6 +82,8 @@ pub const SUPPORTED_CAPABILITIES: &[spirv::Capability] = &[ spirv::Capability::GroupNonUniformBallot, spirv::Capability::GroupNonUniformShuffle, spirv::Capability::GroupNonUniformShuffleRelative, + spirv::Capability::RuntimeDescriptorArray, + spirv::Capability::StorageImageMultisample, // tricky ones spirv::Capability::UniformBufferArrayDynamicIndexing, spirv::Capability::StorageBufferArrayDynamicIndexing, @@ -90,6 +92,7 @@ pub const SUPPORTED_EXTENSIONS: &[&str] = &[ "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_vulkan_memory_model", "SPV_KHR_multiview", + "SPV_EXT_descriptor_indexing", "SPV_EXT_shader_atomic_float_add", "SPV_KHR_16bit_storage", ]; @@ -2799,6 +2802,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> { let options = image::SamplingOptions { compare: false, project: false, + gather: false, }; self.parse_image_sample( extra, @@ -2815,6 +2819,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> { let options = image::SamplingOptions { compare: false, project: true, + gather: false, }; self.parse_image_sample( extra, @@ -2831,6 +2836,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> { let options = image::SamplingOptions { compare: true, project: false, + gather: false, }; self.parse_image_sample( extra, @@ -2847,6 +2853,41 @@ impl<I: Iterator<Item = u32>> Frontend<I> { let options = image::SamplingOptions { compare: true, project: true, + gather: false, + }; + self.parse_image_sample( + extra, + options, + ctx, + &mut emitter, + &mut block, + block_id, + body_idx, + )?; + } + Op::ImageGather => { + let extra = inst.expect_at_least(6)?; + let options = image::SamplingOptions { + compare: false, + project: false, + gather: true, + }; + self.parse_image_sample( + extra, + options, + ctx, + &mut emitter, + &mut block, + block_id, + body_idx, + )?; + } + Op::ImageDrefGather => { + let extra = inst.expect_at_least(6)?; + let options = image::SamplingOptions { + compare: true, + project: false, + gather: true, }; self.parse_image_sample( extra, @@ -3869,7 +3910,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> { crate::Barrier::TEXTURE, semantics & spirv::MemorySemantics::IMAGE_MEMORY.bits() != 0, ); + + block.extend(emitter.finish(ctx.expressions)); block.push(crate::Statement::ControlBarrier(flags), span); + emitter.start(ctx.expressions); } else { log::warn!("Unsupported barrier execution scope: {exec_scope}"); } @@ -3911,7 +3955,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> { crate::Barrier::TEXTURE, semantics & spirv::MemorySemantics::IMAGE_MEMORY.bits() != 0, ); + + block.extend(emitter.finish(ctx.expressions)); block.push(crate::Statement::MemoryBarrier(flags), span); + emitter.start(ctx.expressions); } Op::CopyObject => { inst.expect(4)?; diff --git a/third_party/rust/naga/src/front/wgsl/error.rs b/third_party/rust/naga/src/front/wgsl/error.rs @@ -127,11 +127,7 @@ impl core::fmt::Display for ParseError { } } -impl core::error::Error for ParseError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - None - } -} +impl core::error::Error for ParseError {} #[derive(Copy, Clone, Debug, PartialEq)] pub enum ExpectedToken<'a> { diff --git a/third_party/rust/naga/src/proc/constant_evaluator.rs b/third_party/rust/naga/src/proc/constant_evaluator.rs @@ -1178,6 +1178,11 @@ impl<'a> ConstantEvaluator<'a> { crate::MathFunction::Atan => { component_wise_float!(self, span, [arg], |e| { Ok([e.atan()]) }) } + crate::MathFunction::Atan2 => { + component_wise_float!(self, span, [arg, arg1.unwrap()], |y, x| { + Ok([y.atan2(x)]) + }) + } crate::MathFunction::Asinh => { component_wise_float!(self, span, [arg], |e| { Ok([e.asinh()]) }) } @@ -1346,8 +1351,7 @@ impl<'a> ConstantEvaluator<'a> { crate::MathFunction::Cross => self.cross_product(arg, arg1.unwrap(), span), // unimplemented - crate::MathFunction::Atan2 - | crate::MathFunction::Modf + crate::MathFunction::Modf | crate::MathFunction::Frexp | crate::MathFunction::Ldexp | crate::MathFunction::Dot diff --git a/third_party/rust/ron/.cargo-checksum.json b/third_party/rust/ron/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"6dc6d2c276227e8c74bdde75e04e543f42e2a4df39b33f3ac6bdd42de1f53db4","Cargo.lock":"b42af02e62bef286f6c9bd5054b3f6bf04434962560967a0702c88652abc29f9","Cargo.toml":"a9b4b90a20f5bbfd04a0798ebd8d4756bd7221ce4391d0a38692cc56f2e0c9aa","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"fa0598d520497731445a5bc89a2b3d47896d95568bd2be255b7bc43d771b9994","README.md":"70649b85004fc155375a09cfa425646eb861891b36c09729b0aefdb7b1180b06","clippy.toml":"873fc9b7842395d9c61c2265ea4ad391c1de35bb25fd94347f72b4c7fc528329","docs/extensions.md":"b01d8c32d6adf1ece115957bc63400873aad6106a0f5b80e107e57bada605e5b","docs/grammar.md":"3c1f8423e197d234782724f5bf2cde5d6ed03e77ce63ddda7241717846739f81","examples/base64.rs":"a157559fe9932a834c0c42b726fa483ca648a7ceaf762639746410e84d019901","examples/decode.rs":"b8e2db901f0a25070daa0294794da7c95f9a7d61934e9b5b1cbcb131ca70a7d7","examples/decode_file.rs":"92920fc94e22c2aa83f6864e68e16932425655139d21ed3bdca4e5b4e86428e1","examples/encode.rs":"cfded2357414e2ea68580bf8f2333a62c1ae9d9fa70775c56a23dfe158e297be","examples/encode_file.rs":"b055eed27e7f9d8903bbd43e9d559c97578534cf3888635768aac587743c8508","examples/example.ron":"aebd2baff31a62c3aed1ba568b7a7c1165b197d526a1e2c9eb7adb211de8292e","examples/transcode.rs":"7a1e281684243b263d28f90f2836d6098239ae8ab2a0cb9d97ee0b7521ba960e","rustfmt.toml":"10f292ebd4c21ef67c36b6edb79eed7fada8f021c527948dfbeb3a54a5591e59","src/de/id.rs":"ed5be2ef39ad3490dcdebf99bd692299a20dbc66f2a2b67b0db1eb6dab5fd68b","src/de/mod.rs":"08cd27fd8d3f9f755ff3f1031f8a22dcdab6a2a5baefadd63991d3b98af2b458","src/de/tag.rs":"aeabf1a8378f2f4f8dc51861f0a92eb3f7eaefe3ce7924317fb923654a109153","src/de/tests.rs":"5af19a3ff8dc2d29f6d8d8f6953227454f47a9c6497f360b60d9f40d5b2e44c2","src/de/value.rs":"8de9194406494579988b27359d31aad7896903379c975787f20ec08064833d7e","src/error.rs":"4f244e7a14c89c5977814cea1c05946c88b2db1f0036e4e0d6ead97def0cd3df","src/extensions.rs":"e37b7658ab1fb7adbb09e5c6be4a44f28ee2dae6bc90f3adb66ee68283b768ef","src/lib.rs":"4938899ae50859914ba933bc3bce5778654b427d27a77da65009b85ff0d14f9b","src/options.rs":"041c172cab30d09b4a7b5f8737c5c12c32bb44131cf5963b4c9cdef3ddc8679f","src/parse.rs":"a6e8944c74ef17d963c795e614d32014d1eda098965a599e1b4539312c522fb0","src/ser/mod.rs":"cd7eeff262566d36179faca7d4b2351aabc49553f7c953ea79d94241cbe68164","src/ser/path_meta.rs":"fb74b63bdb8ed570f071670e4ca68886ae1c25611a0cd68fdc540d652680b08c","src/ser/raw.rs":"ae5369904a4db31a36eb966204d96592fde92ab2dfb18165f010a9cf13b8b0dd","src/ser/tests.rs":"61aa2d6d18be8040b305e4962d0c80e5b402101f23204139f8e4a76e958c6c4d","src/ser/value.rs":"476f186322ba027219b0d01b5a1bcdaa33ccbeeb24ab062a477e6128816a6177","src/value/map.rs":"09de618c465e4291b59162ba61b1dc0f689f87910ba86b46fdc362396616c954","src/value/mod.rs":"c1fccd91db3024038d0e37f2925cbc2a831a5714bce8706290c4b6151253b1c8","src/value/number.rs":"3bcba7b23ab9f8b4e1cc172e9543af99cd645c67894389f660279264e043f803","src/value/raw.rs":"22127a25e79750c0108f6b801665d5dc731683ad6538154b04ed9e2e5518c090","tests/115_minimal_flattening.rs":"3bc62fa93ddc6abf5ea504090cdf09b6fd65e1e2bff27c42454054c732f732f5","tests/117_untagged_tuple_variant.rs":"dc69fb057595cc72b379994e76217315761484a455c7ba45aceb445af9c36403","tests/123_enum_representation.rs":"c296885ed5dcd3a7b5230d639aa7632c1c6291460e73dd394b0cd9e69219de31","tests/129_indexmap.rs":"a55ed888407dce347035893afa6a5e60d3e2f92672287c93cf5e21bb19218a40","tests/147_empty_sets_serialisation.rs":"102daa5648f4aaa461d3dc79a9124ff57c92d6c361c2aa20a3f966a0c0908823","tests/152_bitflags.rs":"e93d135e4da6c591f697be7d3b4c116d9151ab52111fe39fda94926f384ad563","tests/203_error_positions.rs":"9c5654a7dbde482040dc11521dd7db0f71dc42e5782d1df9908911c42ce4ff7e","tests/207_adjacently_tagged_enum.rs":"f2ebdf4268eeb6be95fd249c10930e4ea8f4fd4e3452d1ae8799334db2a3b96e","tests/217_nested_untagged_enums.rs":"91f7f0d344b256c707091a8985a1a15e799796ed757901077e3fe5a230c4ecae","tests/238_array.rs":"b0cae4bbe6303da34a58f8c28484856eebccc1728e21847cc2651a30dfd7346d","tests/240_array_pretty.rs":"7cedc29d8bdd9bf40941f3e28a8f1200e72c5211d5e52376e5d5be9076286e36","tests/250_variant_newtypes.rs":"be8eb265ead0386319f17d9340c6897f6ee7945177e541874e60d00d63a9a9a1","tests/254_typetag.rs":"e20c1464eaf2db561444c27fbdf4d73bc6e312e0c57915b7611b06f74a0dc654","tests/256_comma_error.rs":"dd9dc3440c779b45cbcc9cdc39937d1b7045530cdea7255025aaf5a1f1fe023d","tests/289_enumerate_arrays.rs":"0e1e9bd624b756714c6d79b79c388972c4b443c331d08098d585a85cba519bb5","tests/301_struct_name_mismatch.rs":"b980a004edadc4829479e96f897290de25c34c4efb364e5a7d8bd695fdfb78c0","tests/307_stack_overflow.rs":"b8affab09acdb6594242e7142e2fc9f6cd0f3bf36337129dc42b11f8d72060f5","tests/321_unicode_ident.rs":"b32560400d21a633734b366c743a13d972afc12c1d73552485f93a397d8b349a","tests/322_escape_idents.rs":"4f8912aeb24655a378049919ffc8b270519849abcb34ef9d7c34af5be1ec72f3","tests/337_value_float_roundtrip.rs":"e1d2b0ab6ded31fae940b1a937166c385711e68c1f9c716aead7abbeaf17ea01","tests/357_untagged_enum_roundtrip.rs":"193e1804f79bb20b93a9a80203fa64952d811bda6676d808947ac33ec27c2a90","tests/359_deserialize_seed.rs":"be8d0ce834f68496cc90d05b2a0688c105c51883318e3eb362ce7c646d4dc5fe","tests/367_implicit_some.rs":"0c4ebdb13872079954b83ea1a89e0d1fb4714b406fd9dcac976754534e9e36d5","tests/370_float_parsing.rs":"ddb7c92cf6ec9cc5048c97d6199ecc6e32bb68daa5521f381cfad1b841eac106","tests/393_serde_errors.rs":"0f9471ea1f5117df6916d0100f3cdb1073c7e9e0ba2da28caa7dfe7e1c63ab13","tests/401_raw_identifier.rs":"7512950a2db5c527525c145c746297375780e5e6da7db900b1caf58b595e093f","tests/407_raw_value.rs":"7b3107498cb384ad9a8cf7803c521933e4571dc297fe2c78118f8280f69bb4f3","tests/410_trailing_comma.rs":"c8755b2805f26f0d9b748f4277a8d8eea85227af06788ae533cf7b96a8b9e724","tests/423_de_borrowed_identifier.rs":"b3adbdf97d7082d7fea2b2649bb6d50e3e7b320049671dad6d803c003a15586f","tests/425_escape_strings.rs":"d30a63591d5f517b33ac3aaac927a10e1f22d673083497847d0d08b243d2e6b5","tests/436_untagged_bytes.rs":"88fe49032243fd62b5b004c62b369cef25f0d38c4fc2679899f6f0a70b5ff303","tests/438_rusty_byte_strings.rs":"13833d174938d249c2e999eb4e1503d7744ca1504dfa397091127d25e87ab724","tests/447_compact_maps_structs.rs":"cff3aa89e123e8c8098e49e4b1c4f2725f94c8eb1d2ed2abd7cff46695e1df29","tests/449_tagged_enum.rs":"bf21e40e14ea1d39460396af510ca8a1378d7bee489e369fb3dcc3f2fc96f617","tests/462_bytes.rs":"b58b44538525a560c19bb84d64236b9fc61e6a09c117e5c4581f8fe39a8251a3","tests/465_implicit_some_stack.rs":"05621c22436766e7f38d675137aedeb94efbb2c15a761952701cd1a8fe6fb120","tests/465_no_comment_char_value.rs":"bf1b7aae4b4c5e982511e13cddc1fd2eca9c52173d747ce8f829c3e9d99ba55e","tests/465_r_name_value.rs":"17e87a47b5a22d0f068698d557bd46e5d64c3083b1906c8a0fede56529a06d19","tests/465_ser_backslash_string.rs":"871629c618ce378ae0ce27c49c44fd3b95add29b01fde02eb452fa11fc35a575","tests/465_unwrap_some_newtype_variant_value.rs":"6a8ffe1939894d7dedfeafbf73cfe19ca1c665beb892deaadd25bfe1fabb923c","tests/465_validate_ser_identifiers.rs":"84d407d71666312538a6ccd3b350ad025e6199a65c48364705dfd5a2ad16930a","tests/481_number_underscores_suffixes.rs":"16ebad0c50f88c8750bd770d405b88ea00914f210230f4aaeca2a873207084b8","tests/492_enum_in_untagged_enum.rs":"ecf9a5e190317ecdc5f4688b82de0266a6d15712f5d8f19599dff35efa3d4b15","tests/502_known_bugs.rs":"34d2d723c2eeecad0316a17056d7d48d7c4e48660065697f90110301bbcda945","tests/508_value_adjacently_tagged_bug.rs":"3460ecf769a04e73f8adcc97f6548657c337466c23cb69a111f892e10667a582","tests/511_deserialize_any_map_string_key.rs":"45cf9624ce56eb64616c951291a322abfdc65f41ced7105cc74b754a386ad35b","tests/522_explicit_struct_names.rs":"c1405f6e31157d042e7cb4ea61c15127bc15b5c785b3ca7121b0ec1f8ef6e24c","tests/526_flatten.rs":"96ad9a3934a83266b662c06cb6b71425999d8ff9751bed9250dd8a10def2f3b7","tests/530_untagged_union.rs":"13623c4dc2deb98bc05537daa0a557568314e98bba86c4059d60b0fc2db10354","tests/544_path_meta.rs":"3ad38d27ac802e2edc2268093503940a0ecb40d54d96cc91d49376b0e1807832","tests/big_struct.rs":"9c7b41233ae7d0c4fec0727aabd4cea1cd95844c85c0beb5e688b3c79eb43c14","tests/borrowed_str.rs":"24390ee6076ce3896b7cf1b2e202cb3a705c61129a4f62f6c39a2412ca68405f","tests/comments.rs":"251f623fb151b24d874c7c08118b22d4579fcfc8831c0c1c97ab11b8f0edeeb7","tests/depth_limit.rs":"817c0a61576c3133a66bb8c705675a125290f0ccfb92dba8a8aa46a141ad30ce","tests/escape.rs":"4ad32604687f67c64cf7f4757fdded9e1131fb4c65bd5daa8079b1b1c60db7b7","tests/extensions.rs":"4058b5da64c3f9591026790e044d19cf30c744a30cd3e9af79acd70f76ec0d40","tests/floats.rs":"367a22cca7d3a3ce6bdffc30df8712aae348ad29a1adbe9a47bc98e0a51b614d","tests/large_number.rs":"1f823b826e086f35329849d5bd9aac87266933a07988ef380348b406dea32835","tests/min_max.rs":"4529513a4cf1e5c25f7697ba258fdbae258617cf8f3374080843aef048c2bde3","tests/non_identifier_identifier.rs":"b00d2a4994242212f2e3f2c847da3a3634b950060d88b74a7004d704e847f2df","tests/non_string_tag.rs":"4ea293cb6110b3776a103000a50a7276f50acc5aa15aa65f651a2e27a441dbba","tests/numbers.rs":"d28656afd5123df5cec3b8fe01cda8f14b6b3065900b7adbf352776a164dd29b","tests/options.rs":"15d0ebd3ac481aa18b56bc40ef5e28a5e36577f7054632bb26334b0167f2872f","tests/preserve_sequence.rs":"cda4aa098e579cf68837101b8e6b12f5b26e11272cc17d260fa232379c5008bf","tests/preserve_sequence_ex1.ron":"47bdf8da637b6e99701b5a4b8c100b4c9d45440c357aef8d368a406a05394ea9","tests/preserve_sequence_ex2.ron":"9ba759300324f8978469ce616f20eb0cfc134f0a8a1afff884fff5315b32e0d0","tests/roundtrip.rs":"4af0accc1129850537f2e04fcf9c9c1d4ecf25fdd05e79179de8fb7f8596a910","tests/struct_integers.rs":"005ff6238fdd953b822fa0ad87c013370da646bd63f880a476a2d9bbe3da7b57","tests/to_string_pretty.rs":"96b3aaba638f90b66a16693714139ef57ecd8daefd8f87b771ae2bf37b15e985","tests/unicode.rs":"7bb3d2e06d7656fabd1f8940a5abd92af6ffa8652b2f2fa7b0f2b86ce009a3c6","tests/value.rs":"22c53deb9c7b64f6d34fd345dcf5fadcca7e2508714a696b967d42d464fe671b"},"package":"beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f"} -\ No newline at end of file +{"files":{"CHANGELOG.md":"b55480cd4e5e655b1b2c84471b223cc79ee7a9f203e8d015cfb32833e261c395","Cargo.lock":"25764fddd9c2a62e43eaeb22243c1f4ece9eb841f6e2a0744baae618be58aba9","Cargo.toml":"3b0c3781178e687681626725f18768fa1d9c2ad951340c6799d363102210e44d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"fa0598d520497731445a5bc89a2b3d47896d95568bd2be255b7bc43d771b9994","README.md":"70649b85004fc155375a09cfa425646eb861891b36c09729b0aefdb7b1180b06","clippy.toml":"873fc9b7842395d9c61c2265ea4ad391c1de35bb25fd94347f72b4c7fc528329","docs/extensions.md":"b01d8c32d6adf1ece115957bc63400873aad6106a0f5b80e107e57bada605e5b","docs/grammar.md":"3c1f8423e197d234782724f5bf2cde5d6ed03e77ce63ddda7241717846739f81","examples/base64.rs":"c03740931bba10240db25edd928b1e7167b16da3664cb8314f3dc3cd9bc663cf","examples/decode.rs":"b8e2db901f0a25070daa0294794da7c95f9a7d61934e9b5b1cbcb131ca70a7d7","examples/decode_file.rs":"92920fc94e22c2aa83f6864e68e16932425655139d21ed3bdca4e5b4e86428e1","examples/encode.rs":"cfded2357414e2ea68580bf8f2333a62c1ae9d9fa70775c56a23dfe158e297be","examples/encode_file.rs":"b055eed27e7f9d8903bbd43e9d559c97578534cf3888635768aac587743c8508","examples/example.ron":"aebd2baff31a62c3aed1ba568b7a7c1165b197d526a1e2c9eb7adb211de8292e","examples/file_read_write_vec.rs":"d1afa1a6ae4d3bcdb8d9ad3cde235979122ff0a3eaafd92db2b36bebb441d410","examples/transcode.rs":"7a1e281684243b263d28f90f2836d6098239ae8ab2a0cb9d97ee0b7521ba960e","rustfmt.toml":"10f292ebd4c21ef67c36b6edb79eed7fada8f021c527948dfbeb3a54a5591e59","src/de/id.rs":"ed5be2ef39ad3490dcdebf99bd692299a20dbc66f2a2b67b0db1eb6dab5fd68b","src/de/mod.rs":"a5d8f44ed99b1070548227c343dba6bce850a9584bcc42d5f46480380be3d26b","src/de/tag.rs":"0513808804d16ea74f49d937089dd8ae6f74aa0c30f445dd03c7e6db41abce9a","src/de/tests.rs":"fc8a8c168c3b7d510bb9687c88d74f742ce5354b9fb562e5c963efd76b998c5c","src/de/value.rs":"0188558422aa1ec7bb6a36317535073ecb2ce5f23c64e704284d94f3ddea8c4d","src/error.rs":"e9f2d532d158a1293546193602e173dc36715f1086841895bc3dbbd5fd370301","src/extensions.rs":"e37b7658ab1fb7adbb09e5c6be4a44f28ee2dae6bc90f3adb66ee68283b768ef","src/lib.rs":"e536f55f1a73d92fdaa6614b32e1093b0246d7044c176542b110cc8f83307c57","src/options.rs":"99e9d8bba41c5cc74fb741d8db69acd677b649a708661b34ba3467719dd7d419","src/parse.rs":"2e1efbad94a47a18214274863f657b13e144da2a6c138709ddb25ed406db15ad","src/ser/mod.rs":"6dbc0a2423850e5b13322e6345439ae9a1bb03eaf0afd09285bd4cff68f58959","src/ser/path_meta.rs":"d101300d127bb76289b5a9dfc6c674c5af08f27a4ad5088f42f71bf20410a2c0","src/ser/raw.rs":"00a29fc03d3025f0bafed90fdecb216b63ef39ac8ca81b2080a70cc49f6d3d9f","src/ser/tests.rs":"2d28f31b837d370c46af4f2f41230fed73a52ee36021005b9469844cf1b4616f","src/ser/value.rs":"476f186322ba027219b0d01b5a1bcdaa33ccbeeb24ab062a477e6128816a6177","src/util/mod.rs":"f00f9b2861a57f70e9e8ada0abb21577aeb113c65ad27471ce8ebc5e91568003","src/util/span_substring.rs":"66f39c69d2af3c8624fb4f09ef027d353d8ce906ace409334cbd8929fecde1f5","src/value/map.rs":"f89f07492ab3971198bf93b82b0f9acd65a1fdd636aa5467f50242018cd8dfed","src/value/mod.rs":"a1b6607b4f1a9f6d0ae23db2e9849e0517f855d6bc119e6d773ea787c0655f0e","src/value/number.rs":"7b269a26bd66be1552d3b2d656379acb02861adf8b78154b08af93ea5b9ceb70","src/value/raw.rs":"959a6d74a802474b9c87f40557c737280d8e1a50e5dacdf725d4dbba0e501839","tests/115_minimal_flattening.rs":"724a4d981d55dd19e462166b562b5e8659dc637f4f51bcb56ca53049fb4b2c98","tests/117_untagged_tuple_variant.rs":"dc69fb057595cc72b379994e76217315761484a455c7ba45aceb445af9c36403","tests/123_enum_representation.rs":"84346679c262c5f1092d195e2e4dff73fc4779cda7b58bd4242f80168c08a0e7","tests/129_indexmap.rs":"a55ed888407dce347035893afa6a5e60d3e2f92672287c93cf5e21bb19218a40","tests/147_empty_sets_serialisation.rs":"102daa5648f4aaa461d3dc79a9124ff57c92d6c361c2aa20a3f966a0c0908823","tests/152_bitflags.rs":"e93d135e4da6c591f697be7d3b4c116d9151ab52111fe39fda94926f384ad563","tests/203_error_positions.rs":"15c90a298c9766dd8f4239a8aeefe7e0c246f66f2ebfee36c292fff938405214","tests/207_adjacently_tagged_enum.rs":"f2ebdf4268eeb6be95fd249c10930e4ea8f4fd4e3452d1ae8799334db2a3b96e","tests/217_nested_untagged_enums.rs":"91f7f0d344b256c707091a8985a1a15e799796ed757901077e3fe5a230c4ecae","tests/238_array.rs":"d84f1664c09658a322b2bc13eb3ad9cd0a789ad42d1fa66d88147760d4f9dfa9","tests/240_array_pretty.rs":"7cedc29d8bdd9bf40941f3e28a8f1200e72c5211d5e52376e5d5be9076286e36","tests/250_variant_newtypes.rs":"1733d19faba349318c8b5f5179b96252b770b1c1da77d2b08798266d4eeae8a0","tests/254_typetag.rs":"fecad2bd7c8681d900bf2b48159edebe88941a523a8ad3b6bc2ba831cfede771","tests/256_comma_error.rs":"2ca38100def63fe33c0b6e099640c90ddfc334a2df9902bcc4482b803976d691","tests/289_enumerate_arrays.rs":"0e1e9bd624b756714c6d79b79c388972c4b443c331d08098d585a85cba519bb5","tests/301_struct_name_mismatch.rs":"e0b4592367cdd3cd39936364b7cd3dacb526af3b1bfa63fb8e0275d23e38b371","tests/307_stack_overflow.rs":"b8affab09acdb6594242e7142e2fc9f6cd0f3bf36337129dc42b11f8d72060f5","tests/321_unicode_ident.rs":"b32560400d21a633734b366c743a13d972afc12c1d73552485f93a397d8b349a","tests/322_escape_idents.rs":"4f8912aeb24655a378049919ffc8b270519849abcb34ef9d7c34af5be1ec72f3","tests/337_value_float_roundtrip.rs":"e1d2b0ab6ded31fae940b1a937166c385711e68c1f9c716aead7abbeaf17ea01","tests/357_untagged_enum_roundtrip.rs":"193e1804f79bb20b93a9a80203fa64952d811bda6676d808947ac33ec27c2a90","tests/359_deserialize_seed.rs":"f69be820dbee676e6ba64f3e0878ca6e4401e3f6258d0ab525545e376931b1d0","tests/367_implicit_some.rs":"0c4ebdb13872079954b83ea1a89e0d1fb4714b406fd9dcac976754534e9e36d5","tests/370_float_parsing.rs":"3a376c0ea391367618a4dbab987e86d6db43b8f679d1e5d8878e4529bb5c7ab0","tests/393_serde_errors.rs":"5dbedc00337bc14d4b1d0fd3fbf576cdc5038aacb5cc81346e6ecfcefdeef101","tests/401_raw_identifier.rs":"fd08b742afc3106aa412d78b3c010895b6b57d1c95b55f7cf74afcc05c4d32f2","tests/407_raw_value.rs":"00739f879946de24fa5be03c9ff29569bcef5e1415e362ccfce2f8c9f3bd877d","tests/410_trailing_comma.rs":"f40b4195266a7e79f9580f4a848a5fb8d9291aaa50ebdf4820bd12b86d5a960e","tests/423_de_borrowed_identifier.rs":"1dfeba0ec2930289cd85b7ac138ba24d2206f0d5e41422ad2617b5e57590db7f","tests/425_escape_strings.rs":"d30a63591d5f517b33ac3aaac927a10e1f22d673083497847d0d08b243d2e6b5","tests/436_untagged_bytes.rs":"88fe49032243fd62b5b004c62b369cef25f0d38c4fc2679899f6f0a70b5ff303","tests/438_rusty_byte_strings.rs":"77d3f23d04bd7fef75690bee7af66379bc40b3c2ba1d1575e5287d741f7dbb1c","tests/447_compact_maps_structs.rs":"cff3aa89e123e8c8098e49e4b1c4f2725f94c8eb1d2ed2abd7cff46695e1df29","tests/449_tagged_enum.rs":"f6fa229948912123947dad39c8f22a62c06aff949eb4eb7913d1e5c3c4043a6c","tests/462_bytes.rs":"60696488e6c8163ef9eae2b4e439bbfa53b7eb978aff0f282cf0e0eb6dbd4450","tests/465_implicit_some_stack.rs":"b5956d5cca3e96959c899d6eb9811591291f36da3af47920de87248c12e834e0","tests/465_no_comment_char_value.rs":"bf1b7aae4b4c5e982511e13cddc1fd2eca9c52173d747ce8f829c3e9d99ba55e","tests/465_r_name_value.rs":"17e87a47b5a22d0f068698d557bd46e5d64c3083b1906c8a0fede56529a06d19","tests/465_ser_backslash_string.rs":"481c0f07dc9826d7b11711e49da4430847f105918a5925a22aa6396b81ecf9be","tests/465_unwrap_some_newtype_variant_value.rs":"7cf408c90ae816108bfd8eb09464de9e071c64f1d6eb88e87767789e77764ea3","tests/465_validate_ser_identifiers.rs":"84d407d71666312538a6ccd3b350ad025e6199a65c48364705dfd5a2ad16930a","tests/481_number_underscores_suffixes.rs":"2cd8e30381afcad494e93d38e9ae7d330d41b84c143ffb38cf270909116eaead","tests/492_enum_in_untagged_enum.rs":"af6d009025ffb5a7e5818617deb86306fa1fe371737f7dca592d9951f2c55a5e","tests/502_known_bugs.rs":"7788b9c6ce0f3ed5379746800ef6232b3c2502e734e4be1b844aac7b186f51ca","tests/508_value_adjacently_tagged_bug.rs":"d32b2f280d73d2939d5b1f836cab30a076cdddb71343ce8df6d2847f2e86080c","tests/511_deserialize_any_map_string_key.rs":"5beff2bbae16796d0c37d6d16ee3d654d8ebd3b0a2f911b4cb2872f72f21ed33","tests/522_explicit_struct_names.rs":"c1405f6e31157d042e7cb4ea61c15127bc15b5c785b3ca7121b0ec1f8ef6e24c","tests/526_flatten.rs":"96ad9a3934a83266b662c06cb6b71425999d8ff9751bed9250dd8a10def2f3b7","tests/530_untagged_union.rs":"13623c4dc2deb98bc05537daa0a557568314e98bba86c4059d60b0fc2db10354","tests/544_path_meta.rs":"3ad38d27ac802e2edc2268093503940a0ecb40d54d96cc91d49376b0e1807832","tests/564_exhaustive_number.rs":"e953b0c88121c06319c993d89dddb4dd116e547448208d4b8e36126609cc6c12","tests/big_struct.rs":"9c7b41233ae7d0c4fec0727aabd4cea1cd95844c85c0beb5e688b3c79eb43c14","tests/borrowed_str.rs":"24390ee6076ce3896b7cf1b2e202cb3a705c61129a4f62f6c39a2412ca68405f","tests/comments.rs":"243193276f60b0f74d3629156ecb812c0bdd995c0e1ee32666eedfebd8e53f4e","tests/depth_limit.rs":"817c0a61576c3133a66bb8c705675a125290f0ccfb92dba8a8aa46a141ad30ce","tests/escape.rs":"f153a99127d26584ce330a0a0148ee7cb59feff7968011d3705409e1c1a7d8bd","tests/extensions.rs":"4058b5da64c3f9591026790e044d19cf30c744a30cd3e9af79acd70f76ec0d40","tests/floats.rs":"367a22cca7d3a3ce6bdffc30df8712aae348ad29a1adbe9a47bc98e0a51b614d","tests/large_number.rs":"1f823b826e086f35329849d5bd9aac87266933a07988ef380348b406dea32835","tests/min_max.rs":"4529513a4cf1e5c25f7697ba258fdbae258617cf8f3374080843aef048c2bde3","tests/non_identifier_identifier.rs":"75f19fe1225855e8edb87b93d2b97ac21b1e24ab9efd133248b15cb3a76fbd9d","tests/non_string_tag.rs":"6b8d4a8adde053533d3a90afdcc0a00ee27cf6023c60916d411d9c97a1dbb0c8","tests/numbers.rs":"1856a7094235145d06673f817af0dc27645543458bb4d543efa9c546379fdd4a","tests/options.rs":"071faa0f23fdf51d8ae13a84d9d93750574a35570a2d1372243d01a3f29f45ca","tests/preserve_sequence.rs":"cda4aa098e579cf68837101b8e6b12f5b26e11272cc17d260fa232379c5008bf","tests/preserve_sequence_ex1.ron":"47bdf8da637b6e99701b5a4b8c100b4c9d45440c357aef8d368a406a05394ea9","tests/preserve_sequence_ex2.ron":"9ba759300324f8978469ce616f20eb0cfc134f0a8a1afff884fff5315b32e0d0","tests/roundtrip.rs":"4af0accc1129850537f2e04fcf9c9c1d4ecf25fdd05e79179de8fb7f8596a910","tests/struct_integers.rs":"005ff6238fdd953b822fa0ad87c013370da646bd63f880a476a2d9bbe3da7b57","tests/to_string_pretty.rs":"96b3aaba638f90b66a16693714139ef57ecd8daefd8f87b771ae2bf37b15e985","tests/unicode.rs":"98ca3dc19187908989cccca33c07d76e1fd316039453d65ff9bd19249dbb7a25","tests/value.rs":"1fdc1dec740a9ea9d55b44fe904c1fb060170e0fadd05ecac5ffae167a8b3d48"},"package":"db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468"} +\ No newline at end of file diff --git a/third_party/rust/ron/CHANGELOG.md b/third_party/rust/ron/CHANGELOG.md @@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## [0.11.0] - 2025-08-27 + +### API Changes + +- Breaking: `SpannedError` now stores the full error span in span: Span { start: Position, end: Position }`, to facilitate, e.g., language server highlighting of syntax errors. + +- Breaking: Added `no_std` support via a new `std` feature (enabled by default). With default features disabled, you must enable the `std` feature to access `de::from_reader`, and the `std::io` operations on `Options`, such as `from_reader`, `from_reader_seed`, `to_io_writer`, and `to_io_writer_pretty` ([#567](https://github.com/ron-rs/ron/pull/567)) + +- Breaking: Fixed (again) `ron::value::Number` to ensure it is non-exhaustive, to avoid breaking `match`es when feature unification enables more of its variants than expected ([#568](https://github.com/ron-rs/ron/pull/568)) + +### Examples + +- Add a new example `file_read_write_vec.rs` for reading and writing `Vec<T>` to/from files. ([#573](https://github.com/ron-rs/ron/pull/573)) + ## [0.10.1] - 2025-04-08 ### API Changes diff --git a/third_party/rust/ron/Cargo.lock b/third_party/rust/ron/Cargo.lock @@ -10,9 +10,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" dependencies = [ "serde", ] @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" [[package]] name = "heck" @@ -56,9 +56,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "indexmap" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", "hashbrown", @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "inventory" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" dependencies = [ "rustversion", ] @@ -82,9 +82,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "once_cell" @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -122,7 +122,7 @@ dependencies = [ [[package]] name = "ron" -version = "0.10.1" +version = "0.11.0" dependencies = [ "base64", "bitflags", @@ -135,13 +135,14 @@ dependencies = [ "serde_json", "typetag", "unicode-ident", + "unicode-segmentation", ] [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -180,9 +181,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "itoa", "memchr", @@ -192,9 +193,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -236,3 +237,9 @@ name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" diff --git a/third_party/rust/ron/Cargo.toml b/third_party/rust/ron/Cargo.toml @@ -13,7 +13,7 @@ edition = "2021" rust-version = "1.64.0" name = "ron" -version = "0.10.1" +version = "0.11.0" authors = [ "Christopher Durham <cad97@cad97.com>", "Dzmitry Malyshau <kvarkus@gmail.com>", @@ -47,8 +47,14 @@ features = [ rustdoc-args = ["--generate-link-to-definition"] [features] -default = [] +default = ["std"] +indexmap = [ + "std", + "dep:indexmap", +] integer128 = [] +internal-span-substring-test = ["unicode-segmentation"] +std = ["serde/std"] [lib] name = "ron" @@ -57,26 +63,36 @@ path = "src/lib.rs" [[example]] name = "base64" path = "examples/base64.rs" +required-features = [] [[example]] name = "decode" path = "examples/decode.rs" +required-features = [] [[example]] name = "decode_file" path = "examples/decode_file.rs" +required-features = ["std"] [[example]] name = "encode" path = "examples/encode.rs" +required-features = [] [[example]] name = "encode_file" path = "examples/encode_file.rs" +required-features = ["std"] + +[[example]] +name = "file_read_write_vec" +path = "examples/file_read_write_vec.rs" [[example]] name = "transcode" path = "examples/transcode.rs" +required-features = [] [[test]] name = "115_minimal_flattening" @@ -279,6 +295,10 @@ name = "544_path_meta" path = "tests/544_path_meta.rs" [[test]] +name = "564_exhaustive_number" +path = "tests/564_exhaustive_number.rs" + +[[test]] name = "big_struct" path = "tests/big_struct.rs" @@ -356,7 +376,7 @@ path = "tests/value.rs" [dependencies.base64] version = "0.22" -features = ["std"] +features = ["alloc"] default-features = false [dependencies.bitflags] @@ -366,16 +386,13 @@ default-features = false [dependencies.indexmap] version = "2.0" -features = [ - "std", - "serde", -] +features = ["serde"] optional = true default-features = false [dependencies.serde] version = "1.0.181" -features = ["std"] +features = ["alloc"] default-features = false [dependencies.serde_derive] @@ -386,6 +403,11 @@ default-features = false version = "1.0" default-features = false +[dependencies.unicode-segmentation] +version = "1.12.0" +optional = true +default-features = false + [dev-dependencies.bytes] version = "1.3" features = ["serde"] diff --git a/third_party/rust/ron/examples/base64.rs b/third_party/rust/ron/examples/base64.rs @@ -31,7 +31,7 @@ impl ByteStr { impl<'de> Visitor<'de> for ByteStrVisitor { type Value = Vec<u8>; - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a Rusty byte string") } @@ -79,7 +79,7 @@ impl ByteStrOrBase64 { impl<'de> Visitor<'de> for ByteStrOrBase64Visitor { type Value = Vec<u8>; - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a Rusty byte string or a base64-encoded string") } diff --git a/third_party/rust/ron/examples/file_read_write_vec.rs b/third_party/rust/ron/examples/file_read_write_vec.rs @@ -0,0 +1,129 @@ +/// Getting RON with type derives and reading/writing a Vec<T> to/from a file. +use ron::{error::SpannedResult, ser::PrettyConfig, Error}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::{ + fs::File, + io::{Read, Write}, + path::PathBuf, + str::FromStr, +}; + +#[derive(Debug, Deserialize, Serialize)] +struct MetaData { + created_at: String, + author: String, +} + +#[derive(Debug, Deserialize, Serialize)] +enum UserRole { + User, + Admin { key: usize }, +} + +#[derive(Debug, Deserialize, Serialize)] +struct User { + name: String, + email: String, + comment: String, + role: UserRole, + meta: MetaData, +} + +fn create_records() -> Vec<User> { + vec![ + User { + name: "Alice".into(), + email: "alice@example.com".into(), + comment: "New\nLine, and \"quotes\"".into(), + role: UserRole::Admin { key: 0xDEADFEED }, + meta: MetaData { + created_at: "2025-06-22".into(), + author: "Admin".to_string(), + }, + }, + User { + name: "Bob".into(), + email: "bob@example.com".into(), + comment: "Tabs\ttoo".into(), + role: UserRole::User, + meta: MetaData { + created_at: "2025-06-22".into(), + author: "Admin".to_string(), + }, + }, + ] +} + +/// Serializes a list of T into a string with one record per line +fn write_ron_vec_to_str<T: Serialize>(records: &[T]) -> Result<String, Error> { + let mut mut_str = String::new(); + + let as_strings = { + records + .into_iter() + .map(|record| { + ron::ser::to_string_pretty( + &record, + PrettyConfig::new() + .compact_arrays(true) + .compact_maps(true) + .compact_structs(true) + .escape_strings(true), + ) + }) + .collect::<Result<Vec<_>, _>>()? + }; + + as_strings.into_iter().for_each(|s| { + mut_str.push_str(&s); + mut_str.push_str(if cfg!(not(target_os = "windows")) { + "\n" + } else { + "\r\n" + }) + }); + + Ok(mut_str) +} + +/// Serializes a list of T into a text file with one record per line +fn write_ron_vec_to_file<T: Serialize>(path: &PathBuf, records: &[T]) -> Result<usize, Error> { + let mut file = File::create(path).map_err(|e| Error::Io(e.to_string()))?; + + file.write(write_ron_vec_to_str(records)?.as_bytes()) + .map_err(|err| Error::Io(err.to_string())) +} + +/// This reader assumes that every row has one entry, so it would not work if they are split across lines. +fn read_ron_vec_from_str<T: DeserializeOwned>(s: &str) -> SpannedResult<Vec<T>> { + s //_ + .lines() + .map(|s| ron::from_str::<T>(s)) + .collect::<Result<Vec<_>, _>>() +} + +fn read_ron_vec_from_file<T: DeserializeOwned>(path: &PathBuf) -> Result<Vec<T>, Error> { + let mut file = File::open(path).map_err(|e| Error::Io(e.to_string()))?; + + let mut content = String::new(); + + file.read_to_string(&mut content) + .map_err(|e| Error::Io(e.to_string()))?; + + read_ron_vec_from_str(&content).map_err(|e| e.code) +} + +pub fn main() { + let users = create_records(); + + let path = PathBuf::from_str("vec-example.ron").unwrap(); + + write_ron_vec_to_file(&path, &users).unwrap(); + + let read_users: Vec<User> = read_ron_vec_from_file(&path).unwrap(); + + // Comment this out if you want to view the file: + std::fs::remove_file("vec-example.ron").unwrap(); + + println!("{:?}", read_users); +} diff --git a/third_party/rust/ron/src/de/mod.rs b/third_party/rust/ron/src/de/mod.rs @@ -1,15 +1,17 @@ /// Deserialization module. -use std::{ - io::{self, Write}, - str, +use alloc::{ + borrow::ToOwned, + string::{String, ToString}, + vec::Vec, }; +use core::str; use serde::{ de::{self, DeserializeSeed, Deserializer as _, Visitor}, Deserialize, }; -pub use crate::error::{Error, Position, SpannedError}; +pub use crate::error::{Error, Position, Span, SpannedError}; use crate::{ error::{Result, SpannedResult}, extensions::Extensions, @@ -17,15 +19,15 @@ use crate::{ parse::{NewtypeMode, ParsedByteStr, ParsedStr, Parser, StructType, TupleMode}, }; +#[cfg(feature = "std")] +use std::io; + mod id; mod tag; #[cfg(test)] mod tests; mod value; -const SERDE_CONTENT_CANARY: &str = "serde::__private::de::content::Content"; -const SERDE_TAG_KEY_CANARY: &str = "serde::__private::de::content::TagOrContent"; - /// The RON deserializer. /// /// If you just want to simply deserialize a value, @@ -78,7 +80,10 @@ impl<'de> Deserializer<'de> { Err(SpannedError { code: err.into(), - position: Position::from_src_end(valid_input), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position::from_src_end(valid_input), + }, }) } @@ -100,6 +105,7 @@ impl<'de> Deserializer<'de> { /// A convenience function for building a deserializer /// and deserializing a value of type `T` from a reader. +#[cfg(feature = "std")] pub fn from_reader<R, T>(rdr: R) -> SpannedResult<T> where R: io::Read, @@ -170,8 +176,8 @@ impl<'de> Deserializer<'de> { { // HACK: switch to JSON enum semantics for JSON content // Robust impl blocked on https://github.com/serde-rs/serde/pull/2420 - let is_serde_content = std::any::type_name::<V::Value>() == SERDE_CONTENT_CANARY - || std::any::type_name::<V::Value>() == SERDE_TAG_KEY_CANARY; + let is_serde_content = + is_serde_content::<V::Value>() || is_serde_tag_or_content::<V::Value>(); let old_serde_content_newtype = self.serde_content_newtype; self.serde_content_newtype = false; @@ -323,13 +329,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } else if self.parser.consume_str("()") { return visitor.visit_unit(); } else if self.parser.consume_ident("inf") || self.parser.consume_ident("inff32") { - return visitor.visit_f32(std::f32::INFINITY); + return visitor.visit_f32(core::f32::INFINITY); } else if self.parser.consume_ident("inff64") { - return visitor.visit_f64(std::f64::INFINITY); + return visitor.visit_f64(core::f64::INFINITY); } else if self.parser.consume_ident("NaN") || self.parser.consume_ident("NaNf32") { - return visitor.visit_f32(std::f32::NAN); + return visitor.visit_f32(core::f32::NAN); } else if self.parser.consume_ident("NaNf64") { - return visitor.visit_f64(std::f64::NAN); + return visitor.visit_f64(core::f64::NAN); } // `skip_identifier` does not change state if it fails @@ -670,25 +676,21 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // Detect `#[serde(flatten)]` as a struct deserialised as a map - const SERDE_FLATTEN_CANARY: &[u8] = b"struct "; - struct VisitorExpecting<V>(V); - impl<'de, V: Visitor<'de>> std::fmt::Display for VisitorExpecting<&'_ V> { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + impl<'de, V: Visitor<'de>> core::fmt::Display for VisitorExpecting<&'_ V> { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { self.0.expecting(fmt) } } self.newtype_variant = false; - let mut canary_buffer = [0u8; SERDE_FLATTEN_CANARY.len()]; - std::mem::drop(write!( - canary_buffer.as_mut(), - "{}", - VisitorExpecting(&visitor) - )); - let terminator = if canary_buffer == SERDE_FLATTEN_CANARY { + // TODO: Avoid allocating to perform this check. + let serde_flatten_canary = VisitorExpecting(&visitor) + .to_string() + .starts_with("struct "); + + let terminator = if serde_flatten_canary { Terminator::MapAsStruct } else { Terminator::Map @@ -852,8 +854,7 @@ impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> { K: DeserializeSeed<'de>, { if self.has_element()? { - self.inside_internally_tagged_enum = - std::any::type_name::<K::Value>() == SERDE_TAG_KEY_CANARY; + self.inside_internally_tagged_enum = is_serde_tag_or_content::<K::Value>(); match self.terminator { Terminator::Struct => guard_recursion! { self.de => @@ -878,9 +879,7 @@ impl<'de, 'a> de::MapAccess<'de> for CommaSeparated<'a, 'de> { if self.de.parser.consume_char(':') { self.de.parser.skip_ws()?; - let res = if self.inside_internally_tagged_enum - && std::any::type_name::<V::Value>() != SERDE_CONTENT_CANARY - { + let res = if self.inside_internally_tagged_enum && !is_serde_content::<V::Value>() { guard_recursion! { self.de => seed.deserialize(&mut tag::Deserializer::new(&mut *self.de))? } @@ -1047,3 +1046,19 @@ impl<'de, 'a> de::MapAccess<'de> for SerdeEnumContent<'a, 'de> { result } } + +// ensure that these are the same as in the 449_tagged_enum test +fn is_serde_content<T>() -> bool { + matches!( + core::any::type_name::<T>(), + "serde::__private::de::content::Content" | "serde::__private::de::content::Content<'_>" + ) +} + +fn is_serde_tag_or_content<T>() -> bool { + matches!( + core::any::type_name::<T>(), + "serde::__private::de::content::TagOrContent" + | "serde::__private::de::content::TagOrContent<'_>" + ) +} diff --git a/third_party/rust/ron/src/de/tag.rs b/third_party/rust/ron/src/de/tag.rs @@ -22,7 +22,7 @@ impl<'a, 'b: 'a, 'c> de::Deserializer<'b> for &'c mut Deserializer<'a, 'b> { self.de.deserialize_str(visitor) } - fn deserialize_string<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error> + fn deserialize_string<V>(self, visitor: V) -> core::result::Result<V::Value, Self::Error> where V: Visitor<'b>, { diff --git a/third_party/rust/ron/src/de/tests.rs b/third_party/rust/ron/src/de/tests.rs @@ -1,29 +1,43 @@ +use alloc::{ + borrow::ToOwned, + format, + string::{String, ToString}, + vec, + vec::Vec, +}; + use serde_bytes; use serde_derive::Deserialize; use crate::{ - error::{Error, Position, SpannedError, SpannedResult}, + error::{Error, Position, Span, SpannedError, SpannedResult}, parse::Parser, value::Number, }; +#[cfg(feature = "internal-span-substring-test")] +use crate::util::span_substring::check_error_span_inclusive; + +#[cfg(feature = "internal-span-substring-test")] +use crate::util::span_substring::check_error_span_exclusive; + #[derive(Debug, PartialEq, Deserialize)] struct EmptyStruct1; #[derive(Debug, PartialEq, Deserialize)] struct EmptyStruct2 {} -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Clone, Debug, PartialEq, Deserialize)] struct NewType(i32); -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Deserialize)] #[serde(rename = "")] struct UnnamedNewType(i32); #[derive(Debug, PartialEq, Deserialize)] struct TupleStruct(f32, f32); -#[derive(Debug, PartialEq, Deserialize)] +#[derive(Clone, Debug, PartialEq, Deserialize)] #[serde(rename = "")] struct UnnamedTupleStruct(f32, f32); @@ -64,28 +78,44 @@ fn test_struct() { check_from_str_bytes_reader("NewType(42)", Ok(NewType(42))); check_from_str_bytes_reader("(33)", Ok(NewType(33))); - check_from_str_bytes_reader::<NewType>( - "NewType", - Err(SpannedError { - code: Error::ExpectedNamedStructLike("NewType"), - position: Position { line: 1, col: 8 }, - }), - ); + let bogus_struct = "NewType"; + let expected_err = Err(SpannedError { + code: Error::ExpectedNamedStructLike("NewType"), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 8 }, + }, + }); + check_from_str_bytes_reader::<NewType>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<NewType>(bogus_struct, expected_err, "NewType"); + check_from_str_bytes_reader::<UnnamedNewType>( "", Err(SpannedError { code: Error::ExpectedStructLike, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + }, }), ); check_from_str_bytes_reader("(33)", Ok(UnnamedNewType(33))); - check_from_str_bytes_reader::<UnnamedNewType>( - "Newtype", - Err(SpannedError { - code: Error::ExpectedNamedStructLike(""), - position: Position { line: 1, col: 8 }, - }), - ); + + let bogus_struct = "NewType"; + let expected_err = Err(SpannedError { + code: Error::ExpectedNamedStructLike(""), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 8 }, + }, + }); + + check_from_str_bytes_reader::<UnnamedNewType>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<UnnamedNewType>(bogus_struct, expected_err, "NewType"); check_from_str_bytes_reader("TupleStruct(2,5,)", Ok(TupleStruct(2.0, 5.0))); check_from_str_bytes_reader("(3,4)", Ok(TupleStruct(3.0, 4.0))); @@ -93,22 +123,35 @@ fn test_struct() { "", Err(SpannedError { code: Error::ExpectedNamedStructLike("TupleStruct"), - position: Position { line: 1, col: 1 }, - }), - ); - check_from_str_bytes_reader::<UnnamedTupleStruct>( - "TupleStruct(2,5,)", - Err(SpannedError { - code: Error::ExpectedNamedStructLike(""), - position: Position { line: 1, col: 12 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + }, }), ); + + let bogus_struct = "TupleStruct(2,5,)"; + let expected_err = Err(SpannedError { + code: Error::ExpectedNamedStructLike(""), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 12 }, + }, + }); + check_from_str_bytes_reader::<UnnamedTupleStruct>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<UnnamedTupleStruct>(bogus_struct, expected_err, "TupleStruct"); + check_from_str_bytes_reader("(3,4)", Ok(UnnamedTupleStruct(3.0, 4.0))); check_from_str_bytes_reader::<UnnamedTupleStruct>( "", Err(SpannedError { code: Error::ExpectedStructLike, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + }, }), ); } @@ -126,7 +169,7 @@ fn test_unclosed_limited_seq_struct() { type Value = LimitedStruct; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("struct LimitedStruct") } // GRCOV_EXCL_STOP @@ -147,7 +190,10 @@ fn test_unclosed_limited_seq_struct() { "(", Err(SpannedError { code: Error::ExpectedStructLikeEnd, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + }, }), ) } @@ -165,7 +211,7 @@ fn test_unclosed_limited_seq() { type Value = LimitedSeq; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("an empty sequence") } // GRCOV_EXCL_STOP @@ -186,7 +232,10 @@ fn test_unclosed_limited_seq() { "[", Err(SpannedError { code: Error::ExpectedArrayEnd, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + }, }), ); @@ -212,7 +261,7 @@ fn test_unclosed_limited_map() { type Value = LimitedMap; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("an empty map") } // GRCOV_EXCL_STOP @@ -233,7 +282,10 @@ fn test_unclosed_limited_map() { "{", Err(SpannedError { code: Error::ExpectedMapEnd, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + }, }), ); @@ -260,7 +312,10 @@ fn test_enum() { "B", Err(SpannedError { code: Error::ExpectedStructLike, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + }, }), ); check_from_str_bytes_reader("C(true,3.5,)", Ok(MyEnum::C(true, 3.5))); @@ -276,6 +331,7 @@ fn test_array() { check_from_str_bytes_reader("[2,3,4,]", Ok([2, 3, 4i32].to_vec())); } +#[cfg(feature = "std")] #[test] fn test_map() { use std::collections::HashMap; @@ -339,26 +395,44 @@ y: 2.0 // 2! ); } -fn err<T>(kind: Error, line: usize, col: usize) -> SpannedResult<T> { +fn err<T>( + kind: Error, + (line_start, col_start): (usize, usize), + (line_end, col_end): (usize, usize), +) -> SpannedResult<T> { Err(SpannedError { code: kind, - position: Position { line, col }, + span: Span { + start: Position { + line: line_start, + col: col_start, + }, + end: Position { + line: line_end, + col: col_end, + }, + }, }) } #[test] fn test_err_wrong_value() { + #[cfg(feature = "std")] use std::collections::HashMap; - check_from_str_bytes_reader::<f32>("'c'", err(Error::ExpectedFloat, 1, 1)); - check_from_str_bytes_reader::<String>("'c'", err(Error::ExpectedString, 1, 1)); - check_from_str_bytes_reader::<HashMap<u32, u32>>("'c'", err(Error::ExpectedMap, 1, 1)); - check_from_str_bytes_reader::<[u8; 5]>("'c'", err(Error::ExpectedStructLike, 1, 1)); - check_from_str_bytes_reader::<Vec<u32>>("'c'", err(Error::ExpectedArray, 1, 1)); - check_from_str_bytes_reader::<MyEnum>("'c'", err(Error::ExpectedIdentifier, 1, 1)); + check_from_str_bytes_reader::<f32>("'c'", err(Error::ExpectedFloat, (1, 1), (1, 1))); + check_from_str_bytes_reader::<String>("'c'", err(Error::ExpectedString, (1, 1), (1, 1))); + #[cfg(feature = "std")] + check_from_str_bytes_reader::<HashMap<u32, u32>>( + "'c'", + err(Error::ExpectedMap, (1, 1), (1, 1)), + ); + check_from_str_bytes_reader::<[u8; 5]>("'c'", err(Error::ExpectedStructLike, (1, 1), (1, 1))); + check_from_str_bytes_reader::<Vec<u32>>("'c'", err(Error::ExpectedArray, (1, 1), (1, 1))); + check_from_str_bytes_reader::<MyEnum>("'c'", err(Error::ExpectedIdentifier, (1, 1), (1, 1))); check_from_str_bytes_reader::<MyStruct>( "'c'", - err(Error::ExpectedNamedStructLike("MyStruct"), 1, 1), + err(Error::ExpectedNamedStructLike("MyStruct"), (1, 1), (1, 1)), ); check_from_str_bytes_reader::<MyStruct>( "NotMyStruct(x: 4, y: 2)", @@ -367,21 +441,31 @@ fn test_err_wrong_value() { expected: "MyStruct", found: String::from("NotMyStruct"), }, - 1, - 12, + (1, 1), + (1, 12), ), ); - check_from_str_bytes_reader::<(u8, bool)>("'c'", err(Error::ExpectedStructLike, 1, 1)); - check_from_str_bytes_reader::<bool>("notabool", err(Error::ExpectedBoolean, 1, 1)); - - check_from_str_bytes_reader::<MyStruct>( - "MyStruct(\n x: true)", - err(Error::ExpectedFloat, 2, 8), - ); - check_from_str_bytes_reader::<MyStruct>( - "MyStruct(\n x: 3.5, \n y:)", - err(Error::ExpectedFloat, 3, 7), + check_from_str_bytes_reader::<(u8, bool)>( + "'c'", + err(Error::ExpectedStructLike, (1, 1), (1, 1)), ); + check_from_str_bytes_reader::<bool>("notabool", err(Error::ExpectedBoolean, (1, 1), (1, 1))); + + let bogus_struct = "MyStruct(\n x: true)"; + let expected_err = err(Error::ExpectedFloat, (2, 7), (2, 8)); + + check_from_str_bytes_reader::<MyStruct>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<MyStruct>(bogus_struct, expected_err, " t"); + + let bogus_struct = "MyStruct(\n x: 3.5, \n y:)"; + let expected_err = err(Error::ExpectedFloat, (3, 7), (3, 7)); + + check_from_str_bytes_reader::<MyStruct>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<MyStruct>(bogus_struct, expected_err, ")"); } #[test] @@ -394,7 +478,7 @@ fn test_perm_ws() { #[test] fn untagged() { - #[derive(Deserialize, Debug, PartialEq)] + #[derive(Deserialize, Clone, Debug, PartialEq)] #[serde(untagged)] enum Untagged { U8(u8), @@ -410,13 +494,19 @@ fn untagged() { // - serde content uses deserialize_any, which retriggers the struct type check // - struct type check inside a serde content performs a full newtype check // - newtype check fails on the unclosed struct - check_from_str_bytes_reader::<Untagged>( - "Value(()", - Err(crate::error::SpannedError { - code: crate::Error::Eof, - position: crate::error::Position { line: 1, col: 9 }, - }), - ); + // + let bogus_struct = "Value(()"; + let expected_err = Err(crate::error::SpannedError { + code: crate::Error::Eof, + span: Span { + start: Position { line: 1, col: 8 }, + end: crate::error::Position { line: 1, col: 9 }, + }, + }); + check_from_str_bytes_reader::<Untagged>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<Untagged>(bogus_struct, expected_err, ")"); } #[test] @@ -435,34 +525,51 @@ fn rename() { #[test] fn forgot_apostrophes() { - check_from_str_bytes_reader::<(i32, String)>( - "(4, \"Hello)", - Err(SpannedError { - code: Error::ExpectedStringEnd, - position: Position { line: 1, col: 6 }, - }), - ); + let bogus_struct = "(4, \"Hello)"; + let expected_err = Err(SpannedError { + code: Error::ExpectedStringEnd, + span: Span { + start: Position { line: 1, col: 5 }, + end: Position { line: 1, col: 6 }, + }, + }); + + check_from_str_bytes_reader::<(i32, String)>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<(i32, String)>(bogus_struct, expected_err, "\""); } #[test] fn expected_attribute() { - check_from_str_bytes_reader::<String>("#\"Hello\"", err(Error::ExpectedAttribute, 1, 2)); + check_from_str_bytes_reader::<String>( + "#\"Hello\"", + err(Error::ExpectedAttribute, (1, 2), (1, 2)), + ); } #[test] fn expected_attribute_end() { - check_from_str_bytes_reader::<String>( - "#![enable(unwrap_newtypes) \"Hello\"", - err(Error::ExpectedAttributeEnd, 1, 28), - ); + let bogus_struct = "#![enable(unwrap_newtypes) \"Hello\""; + let expected_err = err(Error::ExpectedAttributeEnd, (1, 27), (1, 28)); + check_from_str_bytes_reader::<String>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<String>(bogus_struct, expected_err, " \""); } #[test] fn invalid_attribute() { - check_from_str_bytes_reader::<String>( - "#![enable(invalid)] \"Hello\"", - err(Error::NoSuchExtension("invalid".to_string()), 1, 18), + let bogus_struct = "#![enable(invalid)] \"Hello\""; + let expected_err = err( + Error::NoSuchExtension("invalid".to_string()), + (1, 11), + (1, 18), ); + check_from_str_bytes_reader::<String>(bogus_struct, expected_err.clone()); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<String>(bogus_struct, expected_err, "invalid"); } #[test] @@ -537,7 +644,7 @@ fn test_numbers() { } fn check_de_any_number< - T: Copy + PartialEq + std::fmt::Debug + Into<Number> + serde::de::DeserializeOwned, + T: Copy + PartialEq + core::fmt::Debug + Into<Number> + serde::de::DeserializeOwned, >( s: &str, cmp: T, @@ -626,7 +733,7 @@ fn test_leading_whitespace() { check_from_str_bytes_reader(" EmptyStruct1", Ok(EmptyStruct1)); } -fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + std::fmt::Debug>( +fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>( ron: &str, check: SpannedResult<T>, ) { @@ -636,8 +743,11 @@ fn check_from_str_bytes_reader<T: serde::de::DeserializeOwned + PartialEq + std: let res_bytes = super::from_bytes::<T>(ron.as_bytes()); assert_eq!(res_bytes, check); - let res_reader = super::from_reader::<&[u8], T>(ron.as_bytes()); - assert_eq!(res_reader, check); + #[cfg(feature = "std")] + { + let res_reader = super::from_reader::<&[u8], T>(ron.as_bytes()); + assert_eq!(res_reader, check); + } } #[test] @@ -665,14 +775,20 @@ fn boolean_struct_name() { "true_", Err(SpannedError { code: Error::ExpectedBoolean, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + }, }), ); check_from_str_bytes_reader::<bool>( "false_", Err(SpannedError { code: Error::ExpectedBoolean, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + }, }), ); } diff --git a/third_party/rust/ron/src/de/value.rs b/third_party/rust/ron/src/de/value.rs @@ -1,4 +1,5 @@ -use std::fmt; +use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec}; +use core::fmt; use serde::{ de::{Error, MapAccess, SeqAccess, Visitor}, @@ -10,7 +11,7 @@ use crate::{ value::{Map, Number, Value}, }; -impl std::str::FromStr for Value { +impl core::str::FromStr for Value { type Err = crate::error::SpannedError; /// Creates a value from a string reference. @@ -237,7 +238,8 @@ impl<'de> Visitor<'de> for ValueVisitor { #[cfg(test)] mod tests { - use std::str::FromStr; + use alloc::vec; + use core::str::FromStr; use super::*; @@ -286,13 +288,16 @@ mod tests { #[test] fn test_tuples_error() { - use crate::de::{Error, Position, SpannedError}; + use crate::de::{Error, Position, Span, SpannedError}; assert_eq!( Value::from_str("Foo:").unwrap_err(), SpannedError { code: Error::TrailingCharacters, - position: Position { col: 4, line: 1 } + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 4 } + } }, ); } @@ -302,9 +307,9 @@ mod tests { assert_eq!( eval("(inf, -inf, NaN)"), Value::Seq(vec![ - Value::Number(Number::new(std::f32::INFINITY)), - Value::Number(Number::new(std::f32::NEG_INFINITY)), - Value::Number(Number::new(std::f32::NAN)), + Value::Number(Number::new(core::f32::INFINITY)), + Value::Number(Number::new(core::f32::NEG_INFINITY)), + Value::Number(Number::new(core::f32::NAN)), ]), ); } @@ -418,7 +423,10 @@ mod tests { "(r#:42)".parse::<Value>().unwrap_err(), crate::error::SpannedError { code: crate::Error::ExpectedString, - position: crate::error::Position { line: 1, col: 4 }, + span: crate::error::Span { + start: crate::error::Position { line: 1, col: 3 }, + end: crate::error::Position { line: 1, col: 4 }, + } }, ); @@ -429,7 +437,10 @@ mod tests { "( /*".parse::<Value>().unwrap_err(), crate::error::SpannedError { code: crate::Error::UnclosedBlockComment, - position: crate::error::Position { line: 1, col: 5 }, + span: crate::error::Span { + start: crate::error::Position { line: 1, col: 3 }, + end: crate::error::Position { line: 1, col: 5 }, + } }, ); } diff --git a/third_party/rust/ron/src/error.rs b/third_party/rust/ron/src/error.rs @@ -1,25 +1,31 @@ -use std::{ - error::Error as StdError, - fmt, io, +use alloc::string::{String, ToString}; +use core::{ + fmt, str::{self, Utf8Error}, }; -use serde::{de, ser}; +use serde::{ + de, + ser::{self, StdError}, +}; use unicode_ident::is_xid_continue; use crate::parse::{is_ident_first_char, is_ident_raw_char}; +#[cfg(feature = "std")] +use std::io; + /// This type represents all possible errors that can occur when /// serializing or deserializing RON data. #[allow(clippy::module_name_repetitions)] #[derive(Clone, Debug, PartialEq, Eq)] pub struct SpannedError { pub code: Error, - pub position: Position, + pub span: Span, } -pub type Result<T, E = Error> = std::result::Result<T, E>; -pub type SpannedResult<T> = std::result::Result<T, SpannedError>; +pub type Result<T, E = Error> = core::result::Result<T, E>; +pub type SpannedResult<T> = core::result::Result<T, SpannedError>; #[derive(Clone, Debug, PartialEq, Eq)] #[non_exhaustive] @@ -115,7 +121,7 @@ pub enum Error { impl fmt::Display for SpannedError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}: {}", self.position, self.code) + write!(f, "{}: {}", self.span, self.code) } } @@ -312,6 +318,25 @@ impl fmt::Display for Position { } } +#[derive(Clone, Debug, PartialEq, Eq)] +/// Spans select a range of text between two positions. +/// Spans are used in [`SpannedError`] to indicate the start and end positions +/// of the parser cursor before and after it encountered an error in parsing. +pub struct Span { + pub start: Position, + pub end: Position, +} + +impl fmt::Display for Span { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.start == self.end { + write!(f, "{}", self.start) + } else { + write!(f, "{}-{}", self.start, self.end) + } + } +} + impl ser::Error for Error { #[cold] fn custom<T: fmt::Display>(msg: T) -> Self { @@ -346,7 +371,7 @@ impl de::Error for Error { de::Unexpected::Str(s) => write!(f, "the string {:?}", s), de::Unexpected::Bytes(b) => write!(f, "the byte string b\"{}\"", { b.iter() - .flat_map(|c| std::ascii::escape_default(*c)) + .flat_map(|c| core::ascii::escape_default(*c)) .map(char::from) .collect::<String>() }), @@ -409,6 +434,7 @@ impl de::Error for Error { } impl StdError for SpannedError {} + impl StdError for Error {} impl From<Utf8Error> for Error { @@ -423,6 +449,7 @@ impl From<fmt::Error> for Error { } } +#[cfg(feature = "std")] impl From<io::Error> for Error { fn from(e: io::Error) -> Self { Error::Io(e.to_string()) @@ -484,13 +511,16 @@ impl<'a> fmt::Display for Identifier<'a> { #[cfg(test)] mod tests { + use alloc::{format, string::String}; + use serde::{de::Error as DeError, de::Unexpected, ser::Error as SerError}; - use super::{Error, Position, SpannedError}; + use super::{Error, Position, Span, SpannedError}; #[test] fn error_messages() { - check_error_message(&Error::from(std::fmt::Error), "Formatting RON failed"); + check_error_message(&Error::from(core::fmt::Error), "Formatting RON failed"); + #[cfg(feature = "std")] check_error_message( &Error::from(std::io::Error::new( std::io::ErrorKind::InvalidData, @@ -576,7 +606,7 @@ mod tests { check_error_message(&Error::UnexpectedChar('🦀'), "Unexpected char \'🦀\'"); #[allow(invalid_from_utf8)] check_error_message( - &Error::Utf8Error(std::str::from_utf8(b"error: \xff\xff\xff\xff").unwrap_err()), + &Error::Utf8Error(core::str::from_utf8(b"error: \xff\xff\xff\xff").unwrap_err()), "invalid utf-8 sequence of 1 bytes from index 7", ); check_error_message( @@ -679,7 +709,7 @@ mod tests { ); } - fn check_error_message<T: std::fmt::Display>(err: &T, msg: &str) { + fn check_error_message<T: core::fmt::Display>(err: &T, msg: &str) { assert_eq!(format!("{}", err), msg); } @@ -688,14 +718,20 @@ mod tests { assert_eq!( Error::from(SpannedError { code: Error::Eof, - position: Position { line: 1, col: 1 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 5 }, + } }), Error::Eof ); assert_eq!( Error::from(SpannedError { code: Error::ExpectedRawValue, - position: Position { line: 1, col: 1 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 5 }, + } }), Error::ExpectedRawValue ); diff --git a/third_party/rust/ron/src/lib.rs b/third_party/rust/ron/src/lib.rs @@ -12,8 +12,17 @@ #![deny(clippy::unreachable)] #![deny(unsafe_code)] #![allow(clippy::missing_errors_doc)] // FIXME +#![warn(clippy::alloc_instead_of_core)] +#![warn(clippy::std_instead_of_alloc)] +#![warn(clippy::std_instead_of_core)] #![doc = include_str!("../README.md")] -#![doc(html_root_url = "https://docs.rs/ron/0.10.1")] +#![doc(html_root_url = "https://docs.rs/ron/0.11.0")] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; + +extern crate alloc; pub mod de; pub mod ser; @@ -24,6 +33,7 @@ pub mod value; pub mod extensions; pub mod options; +pub mod util; pub use de::{from_str, Deserializer}; pub use error::{Error, Result}; diff --git a/third_party/rust/ron/src/options.rs b/third_party/rust/ron/src/options.rs @@ -1,17 +1,25 @@ //! Roundtrip serde Options module. -use std::{fmt, io}; +use alloc::string::String; +use core::fmt; use serde::{de, ser}; use serde_derive::{Deserialize, Serialize}; use crate::{ de::Deserializer, - error::{Position, Result, SpannedError, SpannedResult}, + error::{Result, SpannedResult}, extensions::Extensions, ser::{PrettyConfig, Serializer}, }; +#[cfg(feature = "std")] +use { + crate::error::{Position, Span, SpannedError}, + alloc::vec::Vec, + std::io, +}; + /// Roundtrip serde options. /// /// # Examples @@ -92,12 +100,13 @@ impl Options { impl Options { /// A convenience function for building a deserializer /// and deserializing a value of type `T` from a reader. + #[cfg(feature = "std")] pub fn from_reader<R, T>(&self, rdr: R) -> SpannedResult<T> where R: io::Read, T: de::DeserializeOwned, { - self.from_reader_seed(rdr, std::marker::PhantomData) + self.from_reader_seed(rdr, core::marker::PhantomData) } /// A convenience function for building a deserializer @@ -106,7 +115,7 @@ impl Options { where T: de::Deserialize<'a>, { - self.from_str_seed(s, std::marker::PhantomData) + self.from_str_seed(s, core::marker::PhantomData) } /// A convenience function for building a deserializer @@ -115,7 +124,7 @@ impl Options { where T: de::Deserialize<'a>, { - self.from_bytes_seed(s, std::marker::PhantomData) + self.from_bytes_seed(s, core::marker::PhantomData) } /// A convenience function for building a deserializer @@ -123,6 +132,7 @@ impl Options { /// and a seed. // FIXME: panic is not actually possible, remove once utf8_chunks is stabilized #[allow(clippy::missing_panics_doc)] + #[cfg(feature = "std")] pub fn from_reader_seed<R, S, T>(&self, mut rdr: R, seed: S) -> SpannedResult<T> where R: io::Read, @@ -139,15 +149,18 @@ impl Options { // Try to compute a good error position for the I/O error // FIXME: use [`utf8_chunks`](https://github.com/rust-lang/rust/issues/99543) once stabilised #[allow(clippy::expect_used)] - let valid_input = match std::str::from_utf8(&bytes) { + let valid_input = match core::str::from_utf8(&bytes) { Ok(valid_input) => valid_input, - Err(err) => std::str::from_utf8(&bytes[..err.valid_up_to()]) + Err(err) => core::str::from_utf8(&bytes[..err.valid_up_to()]) .expect("source is valid up to error"), }; Err(SpannedError { code: io_err.into(), - position: Position::from_src_end(valid_input), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position::from_src_end(valid_input), + }, }) } @@ -216,6 +229,7 @@ impl Options { /// This function does not generate any newlines or nice formatting; /// if you want that, you can use /// [`to_io_writer_pretty`][Self::to_io_writer_pretty] instead. + #[cfg(feature = "std")] pub fn to_io_writer<W, T>(&self, writer: W, value: &T) -> Result<()> where W: io::Write, @@ -231,6 +245,7 @@ impl Options { } /// Serializes `value` into `writer` in a pretty way. + #[cfg(feature = "std")] pub fn to_io_writer_pretty<W, T>( &self, writer: W, @@ -278,11 +293,13 @@ impl Options { } // Adapter from io::Write to fmt::Write that keeps the error +#[cfg(feature = "std")] struct Adapter<W: io::Write> { writer: W, error: io::Result<()>, } +#[cfg(feature = "std")] impl<T: io::Write> fmt::Write for Adapter<T> { fn write_str(&mut self, s: &str) -> fmt::Result { match self.writer.write_all(s.as_bytes()) { diff --git a/third_party/rust/ron/src/parse.rs b/third_party/rust/ron/src/parse.rs @@ -1,6 +1,11 @@ #![allow(clippy::identity_op)] -use std::{ +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; +use core::{ char::from_u32 as char_from_u32, str::{self, from_utf8, FromStr, Utf8Error}, }; @@ -8,7 +13,7 @@ use std::{ use unicode_ident::{is_xid_continue, is_xid_start}; use crate::{ - error::{Error, Position, Result, SpannedError, SpannedResult}, + error::{Error, Position, Result, Span, SpannedError, SpannedResult}, extensions::Extensions, value::Number, }; @@ -59,6 +64,7 @@ pub struct Parser<'a> { pub exts: Extensions, src: &'a str, cursor: ParserCursor, + prev_cursor: ParserCursor, } #[derive(Copy, Clone)] // GRCOV_EXCL_LINE @@ -77,7 +83,7 @@ impl PartialEq for ParserCursor { } impl PartialOrd for ParserCursor { - fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { self.cursor.partial_cmp(&other.cursor) } } @@ -93,6 +99,11 @@ impl<'a> Parser<'a> { pre_ws_cursor: 0, last_ws_len: 0, }, + prev_cursor: ParserCursor { + cursor: 0, + pre_ws_cursor: 0, + last_ws_len: 0, + }, }; parser.skip_ws().map_err(|e| parser.span_error(e))?; @@ -119,11 +130,15 @@ impl<'a> Parser<'a> { pub fn span_error(&self, code: Error) -> SpannedError { SpannedError { code, - position: Position::from_src_end(&self.src[..self.cursor.cursor]), + span: Span { + start: Position::from_src_end(&self.src[..self.prev_cursor.cursor]), + end: Position::from_src_end(&self.src[..self.cursor.cursor]), + }, } } pub fn advance_bytes(&mut self, bytes: usize) { + self.prev_cursor = self.cursor; self.cursor.cursor += bytes; } @@ -134,7 +149,7 @@ impl<'a> Parser<'a> { } pub fn skip_next_char(&mut self) { - std::mem::drop(self.next_char()); + core::mem::drop(self.next_char()); } pub fn peek_char(&self) -> Option<char> { @@ -1010,7 +1025,7 @@ impl<'a> Parser<'a> { ParsedByteStr::Slice(b) => b, } .iter() - .flat_map(|c| std::ascii::escape_default(*c)) + .flat_map(|c| core::ascii::escape_default(*c)) .map(char::from) .collect::<String>(); let base64_str = match &base64_str { @@ -1029,12 +1044,12 @@ impl<'a> Parser<'a> { let base64_result = ParsedByteStr::try_from_base64(&base64_str); if cfg!(not(test)) { - // FIXME @juntyr: remove in v0.10 + // FIXME @juntyr: remove in v0.12 #[allow(deprecated)] base64_result.map_err(Error::Base64Error) } else { match base64_result { - // FIXME @juntyr: enable in v0.10 + // FIXME @juntyr: enable in v0.12 Ok(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)), Err(_) => Err(Error::ExpectedByteString), } @@ -1044,12 +1059,12 @@ impl<'a> Parser<'a> { let base64_result = ParsedByteStr::try_from_base64(&base64_str); if cfg!(not(test)) { - // FIXME @juntyr: remove in v0.10 + // FIXME @juntyr: remove in v0.12 #[allow(deprecated)] base64_result.map_err(Error::Base64Error) } else { match base64_result { - // FIXME @juntyr: enable in v0.10 + // FIXME @juntyr: enable in v0.12 Ok(byte_str) => Err(expected_byte_string_found_base64(&base64_str, &byte_str)), Err(_) => Err(Error::ExpectedByteString), } @@ -1141,7 +1156,7 @@ impl<'a> Parser<'a> { 1 => s.push(c as u8), len => { let start = s.len(); - s.extend(std::iter::repeat(0).take(len)); + s.extend(core::iter::repeat(0).take(len)); c.encode_utf8(&mut s[start..]); } }, @@ -1781,7 +1796,10 @@ mod tests { expected: String::from("the Rusty byte string b\"Hello ron!\""), found: String::from("the ambiguous base64 string \"SGVsbG8gcm9uIQ==\"") }, - position: Position { line: 1, col: 19 }, + span: Span { + start: Position { line: 1, col: 2 }, + end: Position { line: 1, col: 19 }, + } } ); @@ -1793,7 +1811,10 @@ mod tests { crate::from_str::<bytes::Bytes>("\"invalid=\"").unwrap_err(), SpannedError { code: Error::ExpectedByteString, - position: Position { line: 1, col: 11 }, + span: Span { + start: Position { line: 1, col: 2 }, + end: Position { line: 1, col: 11 }, + } } ); @@ -1801,7 +1822,10 @@ mod tests { crate::from_str::<bytes::Bytes>("r\"invalid=\"").unwrap_err(), SpannedError { code: Error::ExpectedByteString, - position: Position { line: 1, col: 12 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 12 }, + } } ); } diff --git a/third_party/rust/ron/src/ser/mod.rs b/third_party/rust/ron/src/ser/mod.rs @@ -1,4 +1,5 @@ -use std::{borrow::Cow, fmt}; +use alloc::{borrow::Cow, string::String}; +use core::fmt; use serde::{ser, ser::Serialize}; use serde_derive::{Deserialize, Serialize}; @@ -562,7 +563,7 @@ impl<W: fmt::Write> Serializer<W> { fn serialize_escaped_byte_str(&mut self, value: &[u8]) -> fmt::Result { self.output.write_str("b\"")?; - for c in value.iter().flat_map(|c| std::ascii::escape_default(*c)) { + for c in value.iter().flat_map(|c| core::ascii::escape_default(*c)) { self.output.write_char(char::from(c))?; } self.output.write_char('"')?; @@ -736,7 +737,9 @@ impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> { write!(self.output, "{}", v)?; - if v.fract() == 0.0 { + // Equivalent to v.fract() == 0.0 + // See: https://docs.rs/num-traits/0.2.19/src/num_traits/float.rs.html#459-465 + if v % 1. == 0.0 { write!(self.output, ".0")?; } @@ -754,7 +757,9 @@ impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> { write!(self.output, "{}", v)?; - if v.fract() == 0.0 { + // Equivalent to v.fract() == 0.0 + // See: https://docs.rs/num-traits/0.2.19/src/num_traits/float.rs.html#459-465 + if v % 1. == 0.0 { write!(self.output, ".0")?; } @@ -788,7 +793,7 @@ impl<'a, W: fmt::Write> ser::Serializer for &'a mut Serializer<W> { fn serialize_bytes(self, v: &[u8]) -> Result<()> { // We need to fall back to escaping if the byte string would be invalid UTF-8 if !self.escape_strings() { - if let Ok(v) = std::str::from_utf8(v) { + if let Ok(v) = core::str::from_utf8(v) { return self .serialize_unescaped_or_raw_byte_str(v) .map_err(Error::from); @@ -1371,7 +1376,7 @@ impl<'a, W: fmt::Write> ser::SerializeStruct for Compound<'a, W> { guard_recursion! { self.ser => value.serialize(&mut *self.ser)? }; if let Some((ref mut config, _)) = self.ser.pretty { - std::mem::swap(&mut config.path_meta, &mut restore_field); + core::mem::swap(&mut config.path_meta, &mut restore_field); if let Some(ref mut field) = config.path_meta { if let Some(fields) = field.fields_mut() { diff --git a/third_party/rust/ron/src/ser/path_meta.rs b/third_party/rust/ron/src/ser/path_meta.rs @@ -98,10 +98,16 @@ //! ); //! ``` -use std::collections::HashMap; +use alloc::string::String; use serde_derive::{Deserialize, Serialize}; +#[cfg(feature = "std")] +use std::collections::HashMap as FieldsInner; + +#[cfg(not(feature = "std"))] +use alloc::collections::BTreeMap as FieldsInner; + /// The metadata and inner [`Fields`] of a field. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct Field { @@ -234,7 +240,7 @@ impl Field { /// Mapping of names to [`Field`]s. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct Fields { - fields: HashMap<String, Field>, + fields: FieldsInner<String, Field>, } impl Fields { diff --git a/third_party/rust/ron/src/ser/raw.rs b/third_party/rust/ron/src/ser/raw.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; use serde::{ser, Serialize}; diff --git a/third_party/rust/ron/src/ser/tests.rs b/third_party/rust/ron/src/ser/tests.rs @@ -1,3 +1,5 @@ +use alloc::{format, vec}; + use serde_derive::Serialize; use crate::Number; @@ -99,7 +101,7 @@ fn test_vec() { #[test] fn test_map() { - use std::collections::BTreeMap; + use alloc::collections::BTreeMap; let mut map = BTreeMap::new(); map.insert((true, false), 4); @@ -221,9 +223,9 @@ fn test_any_number_precision() { test_min_max! { i128, u128 } } -fn check_ser_any_number<T: Copy + Into<Number> + std::fmt::Display + serde::Serialize>(n: T) { +fn check_ser_any_number<T: Copy + Into<Number> + core::fmt::Display + serde::Serialize>(n: T) { let mut fmt = format!("{}", n); - if !fmt.contains('.') && std::any::type_name::<T>().contains('f') { + if !fmt.contains('.') && core::any::type_name::<T>().contains('f') { fmt.push_str(".0"); } @@ -289,18 +291,21 @@ fn check_to_string_writer<T: ?Sized + serde::Serialize>(val: &T, check: &str, ch .unwrap(); assert_eq!(ron_str_pretty, check_pretty); - let mut ron_writer = std::ffi::OsString::new(); - super::to_writer(&mut ron_writer, val).unwrap(); - assert_eq!(ron_writer, check); - - let mut ron_writer_pretty = std::ffi::OsString::new(); - super::to_writer_pretty( - &mut ron_writer_pretty, - val, - super::PrettyConfig::default() - .struct_names(true) - .compact_structs(true), - ) - .unwrap(); - assert_eq!(ron_writer_pretty, check_pretty); + #[cfg(feature = "std")] + { + let mut ron_writer = std::ffi::OsString::new(); + super::to_writer(&mut ron_writer, val).unwrap(); + assert_eq!(ron_writer, check); + + let mut ron_writer_pretty = std::ffi::OsString::new(); + super::to_writer_pretty( + &mut ron_writer_pretty, + val, + super::PrettyConfig::default() + .struct_names(true) + .compact_structs(true), + ) + .unwrap(); + assert_eq!(ron_writer_pretty, check_pretty); + } } diff --git a/third_party/rust/ron/src/util/mod.rs b/third_party/rust/ron/src/util/mod.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "internal-span-substring-test")] +pub mod span_substring; diff --git a/third_party/rust/ron/src/util/span_substring.rs b/third_party/rust/ron/src/util/span_substring.rs @@ -0,0 +1,331 @@ +use crate::{ + de::{Position, Span}, + error::SpannedResult, +}; +use alloc::string::String; + +impl Position { + /// Given a Position and a string, return the 0-indexed grapheme index into the + /// string at that position, or [None] if the Position is out of bounds of the string. + #[must_use] + pub fn grapheme_index(&self, s: &str) -> Option<usize> { + use unicode_segmentation::UnicodeSegmentation; + let mut line_no = 1; + let mut col_no = 1; + + if (self.line, self.col) == (1, 1) { + return Some(0); + } + + let mut i = 0; + + // Slightly non-intuitive arithmetic: a zero-length string at line 1, col 1 -> 0 + + if (line_no, col_no) == (self.line, self.col) { + return Some(i); + } + + for ch in s.graphemes(true) { + if (line_no, col_no) == (self.line, self.col) { + return Some(i); + } + + // "\n" and "\r\n" each come through the iterator as a single grapheme + if matches!(ch, "\n" | "\r\n") { + line_no += 1; + col_no = 1; + } else { + col_no += 1; + } + + i += 1; + } + + // ...and a string of length 7 at line 1, col 8 -> 7 + if (line_no, col_no) == (self.line, self.col) { + return Some(i); + } + + None + } +} + +impl Span { + /// Given a `Span` and a string, form the resulting string selected exclusively (as in `[start..end`]) by the `Span` + /// or [`None`] if the span is out of bounds of the string at either end. + #[must_use] + pub fn substring_exclusive(&self, s: &str) -> Option<String> { + use alloc::vec::Vec; + use unicode_segmentation::UnicodeSegmentation; + + if let (Some(start), Some(end)) = (self.start.grapheme_index(s), self.end.grapheme_index(s)) + { + Some(s.graphemes(true).collect::<Vec<&str>>()[start..end].concat()) + } else { + None + } + } + + /// Given a `Span` and a string, form the resulting string selected inclusively (as in `[start..=end]`) by the `Span` + /// or [`None`] if the span is out of bounds of the string at either end. + #[must_use] + pub fn substring_inclusive(&self, s: &str) -> Option<String> { + use alloc::vec::Vec; + use unicode_segmentation::UnicodeSegmentation; + + if let (Some(start), Some(end)) = (self.start.grapheme_index(s), self.end.grapheme_index(s)) + { + Some(s.graphemes(true).collect::<Vec<&str>>()[start..=end].concat()) + } else { + None + } + } +} + +/// Given a string `ron`, a [`SpannedResult`], and a substring, verify that trying to parse `ron` results in an error +/// equal to the [`SpannedResult`] with a Span that exclusively (as in `[start..end]`) selects that substring. +/// Note that there are two versions of this helper, inclusive and exclusive. This is because while the parser cursor +/// arithmetic that computes span positions always produces exclusive spans (as in `[start..end]`), +/// when doing validation against a target substring, the inclusive check including the final grapheme that triggered +/// the error is often a more intuitive target to check against. +/// Meanwhile, if the parser threw an EOF, for example, there is no final grapheme to check, and so +/// only the exclusive check would produce a meaningful result. +#[allow(clippy::unwrap_used)] +#[allow(clippy::missing_panics_doc)] +pub fn check_error_span_exclusive<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>( + ron: &str, + check: SpannedResult<T>, + substr: &str, +) { + let res_str = crate::de::from_str::<T>(ron); + assert_eq!(res_str, check); + + let res_bytes = crate::de::from_bytes::<T>(ron.as_bytes()); + assert_eq!(res_bytes, check); + + #[cfg(feature = "std")] + { + let res_reader = crate::de::from_reader::<&[u8], T>(ron.as_bytes()); + assert_eq!(res_reader, check); + } + + assert_eq!( + check.unwrap_err().span.substring_exclusive(ron).unwrap(), + substr + ); +} + +/// Given a string `ron`, a [`SpannedResult`], and a substring, verify that trying to parse `ron` results in an error +/// equal to the [`SpannedResult`] with a Span that inclusively (as in `[start..=end`]) selects that substring. +/// See [`check_error_span_exclusive`] for the rationale behind both versions of this helper. +#[allow(clippy::unwrap_used)] +#[allow(clippy::missing_panics_doc)] +pub fn check_error_span_inclusive<T: serde::de::DeserializeOwned + PartialEq + core::fmt::Debug>( + ron: &str, + check: SpannedResult<T>, + substr: &str, +) { + let res_str = crate::de::from_str::<T>(ron); + assert_eq!(res_str, check); + + let res_bytes = crate::de::from_bytes::<T>(ron.as_bytes()); + assert_eq!(res_bytes, check); + + #[cfg(feature = "std")] + { + let res_reader = crate::de::from_reader::<&[u8], T>(ron.as_bytes()); + assert_eq!(res_reader, check); + } + + assert_eq!( + check.unwrap_err().span.substring_inclusive(ron).unwrap(), + substr + ); +} + +#[cfg(test)] +mod tests { + use crate::de::{Position, Span}; + + fn span(start: Position, end: Position) -> Span { + Span { start, end } + } + + fn pos(line: usize, col: usize) -> Position { + Position { line, col } + } + + #[test] + fn ascii_basics() { + let text = "hello\nworld"; + + // first char / first col + assert_eq!(pos(1, 1).grapheme_index(text), Some(0)); + + // last char on first line ('o') + assert_eq!(pos(1, 5).grapheme_index(text), Some(4)); + + // start of second line ('w') + assert_eq!(pos(2, 1).grapheme_index(text), Some(6)); + + // span across the `\n` + assert_eq!( + span(pos(1, 4), pos(2, 2)) + .substring_exclusive(text) + .unwrap(), + "lo\nw" + ); + } + + #[test] + fn multibyte_greek() { + let text = "αβγ\ndeux\n三四五\r\nend"; + + // Beta + assert_eq!(pos(1, 2).grapheme_index(text), Some(1)); + + // 三 + assert_eq!(pos(3, 1).grapheme_index(text), Some(9)); + + // e + assert_eq!(pos(4, 1).grapheme_index(text), Some(13)); + + // span from α to start of “deux” + assert_eq!( + span(pos(1, 1), pos(2, 1)) + .substring_exclusive(text) + .unwrap(), + "αβγ\n" + ); + } + + #[test] + fn combining_mark_cluster() { + // é == [0x65, 0xCC, 0x81] in UTF-8 + let text = "e\u{0301}x\n"; + + // grapheme #1 (“é”) + assert_eq!(pos(1, 1).grapheme_index(text), Some(0)); + + // grapheme #2 (“x”) + assert_eq!(pos(1, 2).grapheme_index(text), Some(1)); + + // column 4 is past EOL + assert_eq!(pos(1, 4).grapheme_index(text), None); + + // full span + assert_eq!( + span(pos(1, 1), pos(1, 2)) + .substring_exclusive(text) + .unwrap(), + "e\u{0301}" + ); + } + + #[test] + fn zwj_emoji_cluster() { + let text = "👩👩👧👧 and 👨👩👦"; + + // The family emoji is the first grapheme on the line. + assert_eq!(pos(1, 1).grapheme_index(text), Some(0)); + + assert_eq!(pos(1, 2).grapheme_index(text), Some(1)); + + // Span selecting only the first emoji + assert_eq!( + span(pos(1, 1), pos(1, 2)) + .substring_exclusive(text) + .unwrap(), + "👩👩👧👧" + ); + + // Span selecting only the second emoji + assert_eq!( + span(pos(1, 7), pos(1, 8)) + .substring_exclusive(text) + .unwrap(), + "👨👩👦" + ); + } + + #[test] + fn mixed_newlines() { + let text = "one\r\ntwo\nthree\r\n"; + + // start of “two” (line numbers are 1-based) + assert_eq!(pos(2, 1).grapheme_index(text), Some(4)); + + // “three” + assert_eq!(pos(3, 1).grapheme_index(text), Some(8)); + + // span “two\n” + assert_eq!( + span(pos(2, 1), pos(3, 1)) + .substring_exclusive(text) + .unwrap(), + "two\n" + ); + + // span “two\nthree” + assert_eq!( + span(pos(2, 1), pos(3, 6)) + .substring_exclusive(text) + .unwrap(), + "two\nthree" + ); + } + + #[test] + fn oob_and_error_paths() { + let text = "short"; + + // line past EOF + assert_eq!(pos(2, 1).grapheme_index(text), None); + + // column past EOL + assert_eq!(pos(1, 10).grapheme_index(text), None); + + // span with either endpoint oob → None + assert_eq!(span(pos(1, 1), pos(2, 1)).substring_exclusive(text), None); + } + + #[test] + fn whole_text_span() { + let text = "αβγ\nδεζ"; + let all = span(pos(1, 1), pos(2, 4)); + assert_eq!(&all.substring_exclusive(text).unwrap(), text); + } + + #[test] + fn span_substring_helper() { + assert_eq!( + Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 2, col: 1 }, + } + .substring_exclusive( + "In the first place, there are two sorts of bets, or toh.11 There is the +single axial bet in the center between the principals (toh ketengah), and +there is the cloud of peripheral ones around the ring between members +of the audience (toh kesasi). ", + ) + .unwrap(), + "In the first place, there are two sorts of bets, or toh.11 There is the\n" + ); + + assert_eq!( + Span { + start: Position { line: 2, col: 1 }, + end: Position { line: 3, col: 1 }, + } + .substring_exclusive( + "In the first place, there are two sorts of bets, or toh.11 There is the +single axial bet in the center between the principals (toh ketengah), and +there is the cloud of peripheral ones around the ring between members +of the audience (toh kesasi). ", + ) + .unwrap(), + "single axial bet in the center between the principals (toh ketengah), and\n" + ); + } +} diff --git a/third_party/rust/ron/src/value/map.rs b/third_party/rust/ron/src/value/map.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ cmp::{Eq, Ordering}, hash::{Hash, Hasher}, iter::FromIterator, @@ -11,7 +11,7 @@ use super::Value; /// A [`Value`] to [`Value`] map. /// -/// This structure either uses a [`BTreeMap`](std::collections::BTreeMap) or the +/// This structure either uses a [`BTreeMap`](alloc::collections::BTreeMap) or the /// [`IndexMap`](indexmap::IndexMap) internally. /// The latter can be used by enabling the `indexmap` feature. This can be used /// to preserve the order of the parsed map. @@ -20,9 +20,9 @@ use super::Value; pub struct Map(pub(crate) MapInner); #[cfg(not(feature = "indexmap"))] -type MapInner = std::collections::BTreeMap<Value, Value>; +type MapInner = alloc::collections::BTreeMap<Value, Value>; #[cfg(feature = "indexmap")] -type MapInner = indexmap::IndexMap<Value, Value>; +type MapInner = indexmap::IndexMap<Value, Value, std::collections::hash_map::RandomState>; impl Map { /// Creates a new, empty [`Map`]. @@ -181,6 +181,8 @@ impl Hash for Map { #[cfg(test)] mod tests { + use alloc::{vec, vec::Vec}; + use super::{Map, Value}; #[test] @@ -241,6 +243,7 @@ mod tests { assert_eq!(map.remove(&Value::from("a")), None); } + #[cfg(feature = "std")] #[test] fn map_hash() { assert_same_hash(&Map::new(), &Map::new()); @@ -254,13 +257,14 @@ mod tests { ); } + #[cfg(feature = "std")] fn assert_same_hash(a: &Map, b: &Map) { + use core::hash::{Hash, Hasher}; use std::collections::hash_map::DefaultHasher; - use std::hash::{Hash, Hasher}; assert_eq!(a, b); assert!(a.cmp(b).is_eq()); - assert_eq!(a.partial_cmp(b), Some(std::cmp::Ordering::Equal)); + assert_eq!(a.partial_cmp(b), Some(core::cmp::Ordering::Equal)); let mut hasher = DefaultHasher::new(); a.hash(&mut hasher); diff --git a/third_party/rust/ron/src/value/mod.rs b/third_party/rust/ron/src/value/mod.rs @@ -1,6 +1,7 @@ //! Value module. -use std::{borrow::Cow, cmp::Eq, hash::Hash}; +use alloc::{borrow::Cow, boxed::Box, format, string::String, vec::Vec}; +use core::{cmp::Eq, hash::Hash}; use serde::{ de::{DeserializeOwned, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor}, @@ -256,7 +257,8 @@ impl<'a, 'de> MapAccess<'de> for MapAccessor<'a> { #[cfg(test)] mod tests { - use std::{collections::BTreeMap, fmt::Debug}; + use alloc::{collections::BTreeMap, vec}; + use core::fmt::Debug; use serde::Deserialize; @@ -454,7 +456,7 @@ mod tests { type Value = (); // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a map") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/src/value/number.rs b/third_party/rust/ron/src/value/number.rs @@ -1,4 +1,4 @@ -use std::{ +use core::{ cmp::{Eq, Ordering}, hash::{Hash, Hasher}, }; @@ -17,7 +17,8 @@ use serde::{de::Visitor, Serialize, Serializer}; /// <summary>Exhaustively matching on <code>Number</code> in tests</summary> /// /// If you want to ensure that you exhaustively handle every variant, you can -/// match on the hidden `Number::__NonExhaustive` variant. +/// match on the hidden `Number::__NonExhaustive(x)` variant by using the +/// `x.never() -> !` method. /// /// <div class="warning"> /// Matching on this variant means that your code may break when RON is @@ -54,8 +55,61 @@ pub enum Number { } mod private { + #[derive(Debug, PartialEq, PartialOrd, Eq, Hash, Ord)] + enum _Never {} + #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)] - pub enum Never {} + pub struct Never { + never: &'static _Never, + } + + impl Never { + pub fn never(self) -> ! { + match *self.never {} + } + } + + #[cfg(not(feature = "integer128"))] + /// ```compile_fail + /// # use ron::Number; + /// fn match_number(x: Number) { + /// match x { + /// Number::I8(v) => println!("i8: {}", v), + /// Number::I16(v) => println!("i16: {}", v), + /// Number::I32(v) => println!("i32: {}", v), + /// Number::I64(v) => println!("i64: {}", v), + /// Number::U8(v) => println!("u8: {}", v), + /// Number::U16(v) => println!("u16: {}", v), + /// Number::U32(v) => println!("u32: {}", v), + /// Number::U64(v) => println!("u64: {}", v), + /// Number::F32(v) => println!("f32: {}", v.0), + /// Number::F64(v) => println!("f64: {}", v.0), + /// } + /// } + /// ``` + fn _assert_non_exhaustive_check_fails_not_integer128() {} + + #[cfg(feature = "integer128")] + /// ```compile_fail + /// # use ron::Number; + /// fn match_number(x: Number) { + /// match x { + /// Number::I8(v) => println!("i8: {}", v), + /// Number::I16(v) => println!("i16: {}", v), + /// Number::I32(v) => println!("i32: {}", v), + /// Number::I64(v) => println!("i64: {}", v), + /// Number::I128(v) => println!("i128: {}", v), + /// Number::U8(v) => println!("u8: {}", v), + /// Number::U16(v) => println!("u16: {}", v), + /// Number::U32(v) => println!("u32: {}", v), + /// Number::U64(v) => println!("u64: {}", v), + /// Number::U128(v) => println!("u128: {}", v), + /// Number::F32(v) => println!("f32: {}", v.0), + /// Number::F64(v) => println!("f64: {}", v.0), + /// } + /// } + /// ``` + fn _assert_non_exhaustive_check_fails_integer128() {} } impl Serialize for Number { @@ -76,7 +130,7 @@ impl Serialize for Number { Self::F32(v) => serializer.serialize_f32(v.get()), Self::F64(v) => serializer.serialize_f64(v.get()), #[cfg(not(doc))] - Self::__NonExhaustive(never) => match *never {}, + Self::__NonExhaustive(never) => never.never(), } } } @@ -102,7 +156,7 @@ impl Number { Self::F32(v) => visitor.visit_f32(v.get()), Self::F64(v) => visitor.visit_f64(v.get()), #[cfg(not(doc))] - Self::__NonExhaustive(never) => match *never {}, + Self::__NonExhaustive(never) => never.never(), } } } @@ -240,22 +294,22 @@ impl Number { pub fn into_f64(self) -> f64 { #[allow(clippy::cast_precision_loss)] match self { - Number::I8(v) => f64::from(v), - Number::I16(v) => f64::from(v), - Number::I32(v) => f64::from(v), - Number::I64(v) => v as f64, + Self::I8(v) => f64::from(v), + Self::I16(v) => f64::from(v), + Self::I32(v) => f64::from(v), + Self::I64(v) => v as f64, #[cfg(feature = "integer128")] - Number::I128(v) => v as f64, - Number::U8(v) => f64::from(v), - Number::U16(v) => f64::from(v), - Number::U32(v) => f64::from(v), - Number::U64(v) => v as f64, + Self::I128(v) => v as f64, + Self::U8(v) => f64::from(v), + Self::U16(v) => f64::from(v), + Self::U32(v) => f64::from(v), + Self::U64(v) => v as f64, #[cfg(feature = "integer128")] - Number::U128(v) => v as f64, - Number::F32(v) => f64::from(v.get()), - Number::F64(v) => v.get(), + Self::U128(v) => v as f64, + Self::F32(v) => f64::from(v.get()), + Self::F64(v) => v.get(), #[cfg(not(doc))] - Self::__NonExhaustive(never) => match never {}, + Self::__NonExhaustive(never) => never.never(), } } } @@ -294,22 +348,26 @@ number_from_impl! { Number::F64(F64(f64)) } #[cfg(test)] mod tests { - use std::collections::hash_map::DefaultHasher; - use std::hash::{Hash, Hasher}; - use super::*; - fn hash<T: Hash>(v: &T) -> u64 { - let mut state = DefaultHasher::new(); - v.hash(&mut state); - state.finish() - } - #[test] fn test_nan() { assert_eq!(F32(f32::NAN), F32(f32::NAN)); assert_eq!(F32(-f32::NAN), F32(-f32::NAN)); assert_ne!(F32(f32::NAN), F32(-f32::NAN)); + } + + #[cfg(feature = "std")] + #[test] + fn test_nan_hash() { + use std::collections::hash_map::DefaultHasher; + use std::hash::{Hash, Hasher}; + + fn hash<T: Hash>(v: &T) -> u64 { + let mut state = DefaultHasher::new(); + v.hash(&mut state); + state.finish() + } assert_eq!(hash(&F32(f32::NAN)), hash(&F32(f32::NAN))); assert_eq!(hash(&F32(-f32::NAN)), hash(&F32(-f32::NAN))); diff --git a/third_party/rust/ron/src/value/raw.rs b/third_party/rust/ron/src/value/raw.rs @@ -2,7 +2,8 @@ // https://github.com/serde-rs/json/blob/master/src/raw.rs // Licensed under either of Apache License, Version 2.0 or MIT license at your option. -use std::{fmt, ops::Range}; +use alloc::{borrow::ToOwned, boxed::Box, format, string::String}; +use core::{fmt, ops::Range}; use serde::{de, ser, Deserialize, Serialize}; @@ -30,12 +31,12 @@ impl RawValue { fn from_boxed_str(ron: Box<str>) -> Box<Self> { // Safety: RawValue is a transparent newtype around str - unsafe { std::mem::transmute::<Box<str>, Box<RawValue>>(ron) } + unsafe { core::mem::transmute::<Box<str>, Box<RawValue>>(ron) } } fn into_boxed_str(raw_value: Box<Self>) -> Box<str> { // Safety: RawValue is a transparent newtype around str - unsafe { std::mem::transmute::<Box<RawValue>, Box<str>>(raw_value) } + unsafe { core::mem::transmute::<Box<RawValue>, Box<str>>(raw_value) } } #[allow(clippy::expect_used)] @@ -186,10 +187,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { fn visit_borrowed_str<E: de::Error>(self, ron: &'de str) -> Result<Self::Value, E> { match Options::default().from_str::<de::IgnoredAny>(ron) { Ok(_) => Ok(RawValue::from_borrowed_str(ron)), - Err(err) => Err(de::Error::custom(format!( - "invalid RON value at {}: {}", - err.position, err.code - ))), + Err(err) => Err(de::Error::custom(format!("invalid RON value at {}", err))), } } @@ -220,20 +218,14 @@ impl<'de> Deserialize<'de> for Box<RawValue> { fn visit_str<E: de::Error>(self, ron: &str) -> Result<Self::Value, E> { match Options::default().from_str::<de::IgnoredAny>(ron) { Ok(_) => Ok(RawValue::from_boxed_str(ron.to_owned().into_boxed_str())), - Err(err) => Err(de::Error::custom(format!( - "invalid RON value at {}: {}", - err.position, err.code - ))), + Err(err) => Err(de::Error::custom(format!("invalid RON value at {}", err))), } } fn visit_string<E: de::Error>(self, ron: String) -> Result<Self::Value, E> { match Options::default().from_str::<de::IgnoredAny>(&ron) { Ok(_) => Ok(RawValue::from_boxed_str(ron.into_boxed_str())), - Err(err) => Err(de::Error::custom(format!( - "invalid RON value at {}: {}", - err.position, err.code - ))), + Err(err) => Err(de::Error::custom(format!("invalid RON value at {}", err))), } } diff --git a/third_party/rust/ron/tests/115_minimal_flattening.rs b/third_party/rust/ron/tests/115_minimal_flattening.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use ron::error::Span; use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, PartialEq, Eq, Debug)] @@ -115,7 +116,10 @@ Main({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedString, - position: ron::error::Position { line: 2, col: 9 }, + span: Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 2, col: 9 }, + } }) ); @@ -130,7 +134,10 @@ Main({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedMapColon, - position: ron::error::Position { line: 4, col: 10 }, + span: Span { + start: ron::error::Position { line: 4, col: 10 }, + end: ron::error::Position { line: 4, col: 10 }, + } }) ); @@ -145,7 +152,10 @@ Main({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedString, - position: ron::error::Position { line: 4, col: 9 }, + span: Span { + start: ron::error::Position { line: 4, col: 9 }, + end: ron::error::Position { line: 4, col: 9 }, + } }) ); @@ -160,7 +170,10 @@ Main({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedStringEnd, - position: ron::error::Position { line: 5, col: 10 }, + span: Span { + start: ron::error::Position { line: 5, col: 9 }, + end: ron::error::Position { line: 5, col: 10 }, + } }) ); } @@ -239,7 +252,10 @@ MyType({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedString, - position: ron::error::Position { line: 2, col: 9 }, + span: Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 2, col: 9 }, + } }) ); @@ -253,7 +269,10 @@ MyType({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedMapColon, - position: ron::error::Position { line: 4, col: 10 }, + span: Span { + start: ron::error::Position { line: 4, col: 10 }, + end: ron::error::Position { line: 4, col: 10 }, + } }) ); @@ -267,7 +286,10 @@ MyType({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedString, - position: ron::error::Position { line: 4, col: 9 }, + span: Span { + start: ron::error::Position { line: 4, col: 9 }, + end: ron::error::Position { line: 4, col: 9 }, + } }) ); @@ -281,7 +303,10 @@ MyType({ ), Err(ron::error::SpannedError { code: ron::error::Error::ExpectedStringEnd, - position: ron::error::Position { line: 4, col: 10 }, + span: Span { + start: ron::error::Position { line: 4, col: 9 }, + end: ron::error::Position { line: 4, col: 10 }, + } }) ); } diff --git a/third_party/rust/ron/tests/123_enum_representation.rs b/third_party/rust/ron/tests/123_enum_representation.rs @@ -312,7 +312,7 @@ impl ByteStr { type Value = Vec<u8>; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a Rusty byte string") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/tests/203_error_positions.rs b/third_party/rust/ron/tests/203_error_positions.rs @@ -1,11 +1,17 @@ use std::num::NonZeroU32; -use ron::error::{Error, Position, SpannedError}; +use ron::error::{Error, Position, Span, SpannedError}; use serde::{ de::{Deserialize, Error as DeError, Unexpected}, Deserializer, }; +#[cfg(feature = "internal-span-substring-test")] +use ron::util::span_substring::check_error_span_inclusive; + +#[cfg(feature = "internal-span-substring-test")] +use ron::util::span_substring::check_error_span_exclusive; + #[derive(Debug, serde::Deserialize, PartialEq)] #[serde(deny_unknown_fields)] enum Test { @@ -24,82 +30,124 @@ impl<'de> Deserialize<'de> for TypeError { #[test] fn test_error_positions() { - assert_eq!( - ron::from_str::<TypeError>(" ()"), - Err(SpannedError { - code: Error::InvalidValueForType { - expected: String::from("impossible"), - found: String::from("a unit value"), - }, - position: Position { line: 1, col: 3 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("StructVariant(a: true, b: 0, c: -42)"), - Err(SpannedError { - code: Error::InvalidValueForType { - expected: String::from("a nonzero u32"), - found: String::from("the unsigned integer `0`"), - }, - position: Position { line: 1, col: 28 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("TupleVariant(42)"), - Err(SpannedError { - code: Error::ExpectedDifferentLength { - expected: String::from("tuple variant Test::TupleVariant with 2 elements"), - found: 1, - }, - position: Position { line: 1, col: 16 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("NotAVariant"), - Err(SpannedError { - code: Error::NoSuchEnumVariant { - expected: &["TupleVariant", "StructVariant"], - found: String::from("NotAVariant"), - outer: Some(String::from("Test")), - }, - position: Position { line: 1, col: 12 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("StructVariant(a: true, b: 1, c: -42, d: \"gotcha\")"), - Err(SpannedError { - code: Error::NoSuchStructField { - expected: &["a", "b", "c"], - found: String::from("d"), - outer: Some(String::from("StructVariant")), - }, - position: Position { line: 1, col: 39 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("StructVariant(a: true, c: -42)"), - Err(SpannedError { - code: Error::MissingStructField { - field: "b", - outer: Some(String::from("StructVariant")), - }, - position: Position { line: 1, col: 30 }, - }) - ); - - assert_eq!( - ron::from_str::<Test>("StructVariant(a: true, b: 1, a: false, c: -42)"), - Err(SpannedError { - code: Error::DuplicateStructField { - field: "a", - outer: Some(String::from("StructVariant")), - }, - position: Position { line: 1, col: 31 }, - }) - ); + let bogus_struct = " ()"; + let expected_err = Err(SpannedError { + code: Error::InvalidValueForType { + expected: String::from("impossible"), + found: String::from("a unit value"), + }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + }, + }); + + assert_eq!(ron::from_str::<TypeError>(bogus_struct), expected_err,); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TypeError>(bogus_struct, expected_err, " ("); + + let bogus_struct = "StructVariant(a: true, b: 0, c: -42)"; + let expected_err = Err(SpannedError { + code: Error::InvalidValueForType { + expected: String::from("a nonzero u32"), + found: String::from("the unsigned integer `0`"), + }, + span: Span { + start: Position { line: 1, col: 27 }, + end: Position { line: 1, col: 28 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<Test>(bogus_struct, expected_err, "0,"); + + let bogus_struct = "TupleVariant(42)"; + let expected_err = Err(SpannedError { + code: Error::ExpectedDifferentLength { + expected: String::from("tuple variant Test::TupleVariant with 2 elements"), + found: 1, + }, + span: Span { + start: Position { line: 1, col: 16 }, + end: Position { line: 1, col: 16 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<Test>(bogus_struct, expected_err, ")"); + + let bogus_struct = "NotAVariant"; + let expected_err = Err(SpannedError { + code: Error::NoSuchEnumVariant { + expected: &["TupleVariant", "StructVariant"], + found: String::from("NotAVariant"), + outer: Some(String::from("Test")), + }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 12 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<Test>(bogus_struct, expected_err, "NotAVariant"); + + let bogus_struct = "StructVariant(a: true, b: 1, c: -42, d: \"gotcha\")"; + let expected_err = Err(SpannedError { + code: Error::NoSuchStructField { + expected: &["a", "b", "c"], + found: String::from("d"), + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 38 }, + end: Position { line: 1, col: 39 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<Test>(bogus_struct, expected_err, "d:"); + + let bogus_struct = "StructVariant(a: true, c: -42)"; + let expected_err = Err(SpannedError { + code: Error::MissingStructField { + field: "b", + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 30 }, + end: Position { line: 1, col: 30 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<Test>(bogus_struct, expected_err, ")"); + + let bogus_struct = "StructVariant(a: true, b: 1, a: false, c: -42)"; + let expected_err = Err(SpannedError { + code: Error::DuplicateStructField { + field: "a", + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 30 }, + end: Position { line: 1, col: 31 }, + }, + }); + + assert_eq!(ron::from_str::<Test>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<Test>(bogus_struct, expected_err, "a:"); } diff --git a/third_party/rust/ron/tests/238_array.rs b/third_party/rust/ron/tests/238_array.rs @@ -1,5 +1,5 @@ use ron::{ - error::{Error, Position, SpannedError}, + error::{Error, Position, Span, SpannedError}, value::{Number, Value}, }; @@ -35,7 +35,10 @@ fn test_array() { de, SpannedError { code: Error::ExpectedStructLike, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } } ); diff --git a/third_party/rust/ron/tests/250_variant_newtypes.rs b/third_party/rust/ron/tests/250_variant_newtypes.rs @@ -419,7 +419,7 @@ fn test_serialise_tuple_newtypes() { } fn assert_eq_serialize_roundtrip< - S: Serialize + serde::de::DeserializeOwned + PartialEq + std::fmt::Debug, + S: Serialize + serde::de::DeserializeOwned + PartialEq + core::fmt::Debug, >( value: S, extensions: Extensions, diff --git a/third_party/rust/ron/tests/254_typetag.rs b/third_party/rust/ron/tests/254_typetag.rs @@ -1,4 +1,4 @@ -use std::fmt::Write; +use core::fmt::Write; use serde::{Deserialize, Serialize}; @@ -16,7 +16,7 @@ fn typetag_usage() { } #[typetag::serde(tag = "type")] - trait MyTrait: std::fmt::Debug { + trait MyTrait: core::fmt::Debug { fn do_stuff(&self, buffer: &mut String); } @@ -107,7 +107,7 @@ fn typetag_with_enum() { } #[typetag::serde(tag = "type")] - trait MyTrait: std::fmt::Debug { + trait MyTrait: core::fmt::Debug { fn do_stuff(&self, buffer: &mut String); } diff --git a/third_party/rust/ron/tests/256_comma_error.rs b/third_party/rust/ron/tests/256_comma_error.rs @@ -1,6 +1,9 @@ #![allow(dead_code)] -use ron::error::{Error, Position, SpannedError}; +use ron::error::{Error, Position, Span, SpannedError}; + +#[cfg(feature = "internal-span-substring-test")] +use ron::util::span_substring::check_error_span_inclusive; #[derive(Debug, serde::Deserialize)] struct Test { @@ -19,7 +22,10 @@ fn test_missing_comma_error() { ron::from_str::<(i32, i32)>(tuple_string).unwrap_err(), SpannedError { code: Error::ExpectedComma, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 3, col: 9 }, + end: Position { line: 3, col: 9 } + } } ); @@ -33,7 +39,10 @@ fn test_missing_comma_error() { ron::from_str::<Vec<i32>>(list_string).unwrap_err(), SpannedError { code: Error::ExpectedComma, - position: Position { line: 4, col: 9 } + span: Span { + start: Position { line: 4, col: 9 }, + end: Position { line: 4, col: 9 } + } } ); @@ -46,7 +55,10 @@ fn test_missing_comma_error() { ron::from_str::<Test>(struct_string).unwrap_err(), SpannedError { code: Error::ExpectedComma, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 3, col: 9 }, + end: Position { line: 3, col: 9 } + } } ); @@ -59,7 +71,10 @@ fn test_missing_comma_error() { ron::from_str::<std::collections::HashMap<String, i32>>(map_string).unwrap_err(), SpannedError { code: Error::ExpectedComma, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 3, col: 9 }, + end: Position { line: 3, col: 9 } + } } ); @@ -72,9 +87,25 @@ fn test_missing_comma_error() { ron::from_str::<u8>(extensions_string).unwrap_err(), SpannedError { code: Error::ExpectedComma, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 2, col: 50 }, + end: Position { line: 3, col: 9 } + } } ); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<u8>( + extensions_string, + Err(SpannedError { + code: Error::ExpectedComma, + span: Span { + start: Position { line: 2, col: 50 }, + end: Position { line: 3, col: 9 }, + }, + }), + "\n u", + ); } #[test] diff --git a/third_party/rust/ron/tests/301_struct_name_mismatch.rs b/third_party/rust/ron/tests/301_struct_name_mismatch.rs @@ -1,4 +1,4 @@ -use ron::error::{Error, Position, SpannedError}; +use ron::error::{Error, Position, Span, SpannedError}; use serde::Deserialize; #[derive(Debug, Deserialize, PartialEq)] @@ -30,14 +30,20 @@ fn test_unit_struct_name_mismatch() { expected: "MyUnitStruct", found: String::from("MyUnit") }, - position: Position { line: 1, col: 7 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 7 } + } }), ); assert_eq!( ron::from_str::<MyUnitStruct>("42"), Err(SpannedError { code: Error::ExpectedNamedStructLike("MyUnitStruct"), - position: Position { line: 1, col: 1 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 } + } }), ); } @@ -59,14 +65,20 @@ fn test_tuple_struct_name_mismatch() { expected: "MyTupleStruct", found: String::from("MyTypleStruct") }, - position: Position { line: 1, col: 14 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 14 } + } }), ); assert_eq!( ron::from_str::<MyTupleStruct>("42"), Err(SpannedError { code: Error::ExpectedNamedStructLike("MyTupleStruct"), - position: Position { line: 1, col: 1 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 } + } }), ); } @@ -88,14 +100,20 @@ fn test_newtype_struct_name_mismatch() { expected: "MyNewtypeStruct", found: String::from("MyNewtypeStrucl") }, - position: Position { line: 1, col: 16 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 16 } + } }), ); assert_eq!( ron::from_str::<MyNewtypeStruct>("42"), Err(SpannedError { code: Error::ExpectedNamedStructLike("MyNewtypeStruct"), - position: Position { line: 1, col: 1 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 } + } }), ); } @@ -117,14 +135,20 @@ fn test_struct_name_mismatch() { expected: "MyStruct", found: String::from("MuStryct") }, - position: Position { line: 1, col: 9 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 9 } + } }), ); assert_eq!( ron::from_str::<MyStruct>("42"), Err(SpannedError { code: Error::ExpectedNamedStructLike("MyStruct"), - position: Position { line: 1, col: 1 } + span: Span { + start: ron::error::Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 } + } }), ); } diff --git a/third_party/rust/ron/tests/359_deserialize_seed.rs b/third_party/rust/ron/tests/359_deserialize_seed.rs @@ -17,7 +17,7 @@ fn test_deserialize_seed() { impl<'de> serde::de::Visitor<'de> for Visitor { type Value = i64; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { write!(formatter, "an integer") } @@ -51,7 +51,10 @@ fn test_deserialize_seed() { expected: String::from("an integer"), found: String::from("the string \"a\""), }, - position: ron::error::Position { line: 1, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 4 }, + } }) ); } diff --git a/third_party/rust/ron/tests/370_float_parsing.rs b/third_party/rust/ron/tests/370_float_parsing.rs @@ -1,5 +1,5 @@ use ron::{ - de::{Position, SpannedError}, + de::{Position, Span, SpannedError}, Error, }; @@ -42,7 +42,10 @@ fn test_float_literal_parsing() { ron::from_str::<f64>("1.0e1.0"), Err(SpannedError { code: Error::ExpectedFloat, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } }) ); } diff --git a/third_party/rust/ron/tests/393_serde_errors.rs b/third_party/rust/ron/tests/393_serde_errors.rs @@ -1,4 +1,10 @@ -use ron::error::{Error, Position, SpannedError}; +use ron::error::{Position, Span, SpannedError}; + +#[cfg(feature = "internal-span-substring-test")] +use ron::util::span_substring::check_error_span_inclusive; + +#[cfg(feature = "internal-span-substring-test")] +use ron::util::span_substring::check_error_span_exclusive; #[derive(Debug, serde::Deserialize, PartialEq)] #[serde(deny_unknown_fields)] @@ -38,129 +44,197 @@ fn test_unknown_enum_variant() { assert_eq!( ron::from_str::<TestEnum>("NotAVariant"), Err(SpannedError { - code: Error::NoSuchEnumVariant { + code: ron::Error::NoSuchEnumVariant { expected: &["StructVariant", "NewtypeVariant"], found: String::from("NotAVariant"), outer: Some(String::from("TestEnum")), }, - position: Position { line: 1, col: 12 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 12 }, + } }) ); -} -#[test] -fn test_struct_enum_fields() { - assert_eq!( - ron::from_str::<TestEnum>("StructVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"), + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<TestEnum>( + "NotAVariant", Err(SpannedError { - code: Error::NoSuchStructField { - expected: &["a", "b", "c"], - found: String::from("d"), - outer: Some(String::from("StructVariant")), + code: ron::Error::NoSuchEnumVariant { + expected: &["StructVariant", "NewtypeVariant"], + found: String::from("NotAVariant"), + outer: Some(String::from("TestEnum")), }, - position: Position { line: 1, col: 41 }, - }) - ); - - assert_eq!( - ron::from_str::<TestEnum>("StructVariant(a: true, c: -42)"), - Err(SpannedError { - code: Error::MissingStructField { - field: "b", - outer: Some(String::from("StructVariant")), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 12 }, }, - position: Position { line: 1, col: 30 }, - }) + }), + "NotAVariant", ); +} - assert_eq!( - ron::from_str::<TestEnum>("StructVariant(a: true, b: 'b', a: false, c: -42)"), - Err(SpannedError { - code: Error::DuplicateStructField { - field: "a", - outer: Some(String::from("StructVariant")), - }, - position: Position { line: 1, col: 33 }, - }) - ); +#[test] +fn test_struct_enum_fields() { + let bogus_struct = "StructVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"; + let expected_err = Err(SpannedError { + code: ron::Error::NoSuchStructField { + expected: &["a", "b", "c"], + found: String::from("d"), + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 40 }, + end: Position { line: 1, col: 41 }, + }, + }); + + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, "d:"); + + let bogus_struct = "StructVariant(a: true, c: -42)"; + let expected_err = Err(SpannedError { + code: ron::Error::MissingStructField { + field: "b", + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 30 }, + end: Position { line: 1, col: 30 }, + }, + }); + + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, ")"); + + let bogus_struct = "StructVariant(a: true, b: 'b', a: false, c: -42)"; + let expected_err = Err(SpannedError { + code: ron::Error::DuplicateStructField { + field: "a", + outer: Some(String::from("StructVariant")), + }, + span: Span { + start: Position { line: 1, col: 32 }, + end: Position { line: 1, col: 33 }, + }, + }); + + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, "a:"); } #[test] fn test_newtype_enum_fields() { - assert_eq!( - ron::from_str::<TestEnum>("#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"), - Err(SpannedError { - code: Error::NoSuchStructField { - expected: &["a", "b", "c"], - found: String::from("d"), - outer: Some(String::from("NewtypeVariant")), - }, - position: Position { line: 1, col: 78 }, - }) - ); + let bogus_struct = "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', c: -42, d: \"gotcha\")"; + let expected_err = Err(SpannedError { + code: ron::Error::NoSuchStructField { + expected: &["a", "b", "c"], + found: String::from("d"), + outer: Some(String::from("NewtypeVariant")), + }, + span: Span { + start: Position { line: 1, col: 77 }, + end: Position { line: 1, col: 78 }, + }, + }); - assert_eq!( - ron::from_str::<TestEnum>( - "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, c: -42)" - ), - Err(SpannedError { - code: Error::MissingStructField { - field: "b", - outer: Some(String::from("NewtypeVariant")), - }, - position: Position { line: 1, col: 67 }, - }) - ); + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); - assert_eq!( - ron::from_str::<TestEnum>( - "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', a: false, c: -42)" - ), - Err(SpannedError { - code: Error::DuplicateStructField { - field: "a", - outer: Some(String::from("NewtypeVariant")), - }, - position: Position { line: 1, col: 70 }, - }) - ); + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, "d:"); + + let bogus_struct = "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, c: -42)"; + let expected_err = Err(SpannedError { + code: ron::Error::MissingStructField { + field: "b", + outer: Some(String::from("NewtypeVariant")), + }, + span: Span { + start: Position { line: 1, col: 67 }, + end: Position { line: 1, col: 67 }, + }, + }); + + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, ")"); + + let bogus_struct = + "#![enable(unwrap_variant_newtypes)] NewtypeVariant(a: true, b: 'b', a: false, c: -42)"; + let expected_err = Err(SpannedError { + code: ron::Error::DuplicateStructField { + field: "a", + outer: Some(String::from("NewtypeVariant")), + }, + span: Span { + start: Position { line: 1, col: 69 }, + end: Position { line: 1, col: 70 }, + }, + }); + + assert_eq!(ron::from_str::<TestEnum>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestEnum>(bogus_struct, expected_err, "a:"); } #[test] fn test_struct_fields() { - assert_eq!( - ron::from_str::<TestStruct>("TestStruct(a: true, b: 'b', c: -42, d: \"gotcha\")"), - Err(SpannedError { - code: Error::NoSuchStructField { - expected: &["a", "b", "c"], - found: String::from("d"), - outer: Some(String::from("TestStruct")), - }, - position: Position { line: 1, col: 38 }, - }) - ); + let bogus_struct = "TestStruct(a: true, b: 'b', c: -42, d: \"gotcha\")"; + let expected_err = Err(SpannedError { + code: ron::Error::NoSuchStructField { + expected: &["a", "b", "c"], + found: String::from("d"), + outer: Some(String::from("TestStruct")), + }, + span: Span { + start: Position { line: 1, col: 37 }, + end: Position { line: 1, col: 38 }, + }, + }); + + assert_eq!(ron::from_str::<TestStruct>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestStruct>(bogus_struct, expected_err, "d:"); assert_eq!( ron::from_str::<TestStruct>("TestStruct(a: true, c: -42)"), Err(SpannedError { - code: Error::MissingStructField { + code: ron::Error::MissingStructField { field: "b", outer: Some(String::from("TestStruct")), }, - position: Position { line: 1, col: 27 }, + span: Span { + start: Position { line: 1, col: 27 }, + end: Position { line: 1, col: 27 }, + } }) ); - assert_eq!( - ron::from_str::<TestStruct>("TestStruct(a: true, b: 'b', a: false, c: -42)"), - Err(SpannedError { - code: Error::DuplicateStructField { - field: "a", - outer: Some(String::from("TestStruct")), - }, - position: Position { line: 1, col: 30 }, - }) - ); + let bogus_struct = "TestStruct(a: true, b: 'b', a: false, c: -42)"; + let expected_err = Err(SpannedError { + code: ron::Error::DuplicateStructField { + field: "a", + outer: Some(String::from("TestStruct")), + }, + span: Span { + start: Position { line: 1, col: 29 }, + end: Position { line: 1, col: 30 }, + }, + }); + + assert_eq!(ron::from_str::<TestStruct>(bogus_struct), expected_err); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_inclusive::<TestStruct>(bogus_struct, expected_err, "a:"); } #[test] @@ -170,16 +244,25 @@ fn test_internally_tagged_enum() { // Since the error occurs in serde-generated user code, // after successfully deserialising, we cannot annotate + let bogus_struct = "(type: \"StructVariant\")"; + let expected_err = Err(SpannedError { + code: ron::Error::MissingStructField { + field: "a", + outer: None, + }, + span: Span { + start: Position { line: 1, col: 23 }, + end: Position { line: 1, col: 24 }, + }, + }); + assert_eq!( - ron::from_str::<TestEnumInternal>("(type: \"StructVariant\")"), - Err(SpannedError { - code: Error::MissingStructField { - field: "a", - outer: None, - }, - position: Position { line: 1, col: 24 }, - }) + ron::from_str::<TestEnumInternal>(bogus_struct), + expected_err ); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<TestEnumInternal>(bogus_struct, expected_err, ")"); } #[test] @@ -190,11 +273,14 @@ fn test_adjacently_tagged_enum() { assert_eq!( ron::from_str::<TestEnumAdjacent>("(type: StructVariant, content: (d: 4))"), Err(SpannedError { - code: Error::MissingStructField { + code: ron::Error::MissingStructField { field: "a", outer: Some(String::from("TestEnumAdjacent")), }, - position: Position { line: 1, col: 37 }, + span: Span { + start: Position { line: 1, col: 37 }, + end: Position { line: 1, col: 37 }, + } }) ); } @@ -203,13 +289,22 @@ fn test_adjacently_tagged_enum() { fn test_untagged_enum() { // Note: Errors inside untagged enums are not bubbled up + let bogus_struct = "(a: true, a: false)"; + let expected_err = Err(SpannedError { + code: ron::Error::Message(String::from( + "data did not match any variant of untagged enum TestEnumUntagged", + )), + span: Span { + start: Position { line: 1, col: 19 }, + end: Position { line: 1, col: 20 }, + }, + }); + assert_eq!( - ron::from_str::<TestEnumUntagged>("(a: true, a: false)"), - Err(SpannedError { - code: Error::Message(String::from( - "data did not match any variant of untagged enum TestEnumUntagged" - )), - position: Position { line: 1, col: 20 }, - }) + ron::from_str::<TestEnumUntagged>(bogus_struct), + expected_err ); + + #[cfg(feature = "internal-span-substring-test")] + check_error_span_exclusive::<TestEnumUntagged>(bogus_struct, expected_err, ")"); } diff --git a/third_party/rust/ron/tests/401_raw_identifier.rs b/third_party/rust/ron/tests/401_raw_identifier.rs @@ -1,4 +1,4 @@ -use ron::error::{Error, Position, SpannedError}; +use ron::error::{Position, Span, SpannedError}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] @@ -32,24 +32,27 @@ fn test_invalid_identifiers() { ); assert_eq!( ser, - Err(Error::InvalidIdentifier(String::from("Hello World"))) + Err(ron::Error::InvalidIdentifier(String::from("Hello World"))) ); let ser = ron::ser::to_string_pretty( &EmptyStruct, ron::ser::PrettyConfig::default().struct_names(true), ); - assert_eq!(ser, Err(Error::InvalidIdentifier(String::from("")))); + assert_eq!(ser, Err(ron::Error::InvalidIdentifier(String::from("")))); let de = ron::from_str::<InvalidStruct>("Hello World").unwrap_err(); assert_eq!( de, SpannedError { - code: Error::ExpectedDifferentStructName { + code: ron::Error::ExpectedDifferentStructName { expected: "Hello World", found: String::from("Hello"), }, - position: Position { line: 1, col: 6 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 6 }, + } } ); @@ -57,8 +60,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::ExpectedUnit, - position: Position { line: 1, col: 1 }, + code: ron::Error::ExpectedUnit, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } } ); @@ -72,8 +78,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::ExpectedNamedStructLike("Hello+World"), - position: Position { line: 1, col: 1 }, + code: ron::Error::ExpectedNamedStructLike("Hello+World"), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } }, ); @@ -81,8 +90,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::ExpectedNamedStructLike("Hello+World"), - position: Position { line: 1, col: 1 }, + code: ron::Error::ExpectedNamedStructLike("Hello+World"), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } }, ); @@ -90,8 +102,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::SuggestRawIdentifier(String::from("Hello+World")), - position: Position { line: 1, col: 1 }, + code: ron::Error::SuggestRawIdentifier(String::from("Hello+World")), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } } ); @@ -104,8 +119,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::SuggestRawIdentifier(String::from("ab.cd-ef")), - position: Position { line: 2, col: 9 }, + code: ron::Error::SuggestRawIdentifier(String::from("ab.cd-ef")), + span: Span { + start: Position { line: 1, col: 15 }, + end: Position { line: 2, col: 9 }, + } } ); @@ -118,8 +136,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::SuggestRawIdentifier(String::from("rab.cd-ef")), - position: Position { line: 2, col: 9 }, + code: ron::Error::SuggestRawIdentifier(String::from("rab.cd-ef")), + span: Span { + start: Position { line: 1, col: 15 }, + end: Position { line: 2, col: 9 }, + } } ); @@ -132,12 +153,15 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::NoSuchStructField { + code: ron::Error::NoSuchStructField { expected: &["ab.cd-ef", "really_not_raw"], found: String::from("ab.cd+ef"), outer: Some(String::from("Hello+World")), }, - position: Position { line: 2, col: 19 }, + span: Span { + start: Position { line: 2, col: 11 }, + end: Position { line: 2, col: 19 }, + } } ); @@ -145,8 +169,11 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::SuggestRawIdentifier(String::from("Hello-World")), - position: Position { line: 1, col: 1 }, + code: ron::Error::SuggestRawIdentifier(String::from("Hello-World")), + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } } ); @@ -154,19 +181,22 @@ fn test_invalid_identifiers() { assert_eq!( de, SpannedError { - code: Error::NoSuchEnumVariant { + code: ron::Error::NoSuchEnumVariant { expected: &["Hello-World"], found: String::from("Hello+World"), outer: Some(String::from("RawEnum")), }, - position: Position { line: 1, col: 14 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 14 }, + } } ); let de = ron::from_str::<EmptyStruct>("r#+").unwrap_err(); assert_eq!( format!("{}", de), - r#"1:4: Expected only opening `(`, no name, for un-nameable struct"#, + r#"1:3-1:4: Expected only opening `(`, no name, for un-nameable struct"#, ); } diff --git a/third_party/rust/ron/tests/407_raw_value.rs b/third_party/rust/ron/tests/407_raw_value.rs @@ -1,6 +1,6 @@ use ron::{ de::from_bytes, - error::{Error, Position, SpannedError}, + error::{Error, Position, Span, SpannedError}, from_str, to_string, value::RawValue, }; @@ -47,7 +47,10 @@ fn test_raw_value_invalid() { err, SpannedError { code: Error::TrailingCharacters, - position: Position { line: 1, col: 3 } + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 3 } + } } ); @@ -56,7 +59,10 @@ fn test_raw_value_invalid() { err, SpannedError { code: Error::UnexpectedChar('\0'), - position: Position { line: 1, col: 1 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 } + } } ) } @@ -71,7 +77,10 @@ fn test_raw_value_from_ron() { err, SpannedError { code: Error::TrailingCharacters, - position: Position { line: 1, col: 3 } + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 3 } + } } ); @@ -85,7 +94,10 @@ fn test_raw_value_from_ron() { err, SpannedError { code: Error::Eof, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + } } ); } @@ -108,7 +120,10 @@ fn test_raw_value_into_rust() { err, SpannedError { code: Error::ExpectedInteger, - position: Position { line: 1, col: 10 }, + span: Span { + start: Position { line: 1, col: 9 }, + end: Position { line: 1, col: 10 }, + } } ); } @@ -214,7 +229,7 @@ fn test_boxed_raw_value_deserialise_from_string() { assert_eq!( err, Error::Message(String::from( - "invalid RON value at 1:2: Unexpected end of RON" + "invalid RON value at 1:1-1:2: Unexpected end of RON" )) ); } @@ -273,7 +288,10 @@ fn test_fuzzer_found_issue() { RawValue::from_ron(""), Err(SpannedError { code: Error::Eof, - position: Position { line: 1, col: 1 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 1 }, + } }) ); @@ -287,7 +305,10 @@ fn test_fuzzer_found_issue() { code: Error::Message(String::from( "ron::value::RawValue cannot enable extensions" )), - position: Position { line: 1, col: 27 }, + span: Span { + start: Position { line: 1, col: 27 }, + end: Position { line: 1, col: 27 }, + } }) ); @@ -297,7 +318,10 @@ fn test_fuzzer_found_issue() { code: Error::Message(String::from( "ron::value::RawValue cannot enable extensions" )), - position: Position { line: 1, col: 27 }, + span: Span { + start: Position { line: 1, col: 27 }, + end: Position { line: 1, col: 27 }, + } }) ); @@ -305,14 +329,20 @@ fn test_fuzzer_found_issue() { RawValue::from_ron("42 //"), Err(SpannedError { code: Error::UnclosedLineComment, - position: Position { line: 1, col: 6 }, + span: Span { + start: Position { line: 1, col: 6 }, + end: Position { line: 1, col: 6 }, + } }) ); assert_eq!( ron::from_str::<&RawValue>("42 //"), Err(SpannedError { code: Error::UnclosedLineComment, - position: Position { line: 1, col: 6 }, + span: Span { + start: Position { line: 1, col: 6 }, + end: Position { line: 1, col: 6 }, + } }) ); assert_eq!( @@ -332,14 +362,20 @@ fn test_fuzzer_found_issue() { RawValue::from_ron("a//"), Err(SpannedError { code: Error::UnclosedLineComment, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 4 }, + } }) ); assert_eq!( ron::from_str::<&RawValue>("a//"), Err(SpannedError { code: Error::UnclosedLineComment, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 4 }, + } }) ); assert_eq!( diff --git a/third_party/rust/ron/tests/410_trailing_comma.rs b/third_party/rust/ron/tests/410_trailing_comma.rs @@ -4,9 +4,11 @@ use ron::from_str; use serde::Deserialize; #[derive(Deserialize)] +#[allow(dead_code)] struct Newtype(i32); #[derive(Deserialize)] +#[allow(dead_code)] struct Tuple(i32, i32); #[derive(Deserialize)] diff --git a/third_party/rust/ron/tests/423_de_borrowed_identifier.rs b/third_party/rust/ron/tests/423_de_borrowed_identifier.rs @@ -32,7 +32,7 @@ impl<'de> Visitor<'de> for SerializeDynVisitor { type Value = Box<dyn Any>; // GRCOV_EXCL_START - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { write!(formatter, "a serialize dyn struct") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/tests/438_rusty_byte_strings.rs b/third_party/rust/ron/tests/438_rusty_byte_strings.rs @@ -1,5 +1,5 @@ use ron::{ - error::{Position, SpannedError}, + error::{Position, Span, SpannedError}, Error, }; use serde::Deserialize; @@ -46,7 +46,10 @@ fn v_9_deprecated_base64_bytes_support() { assert_eq!( Err(SpannedError { code: Error::Base64Error(base64::DecodeError::InvalidByte(0, b'_')), - position: Position { line: 1, col: 40 } + span: Span { + start: Position { line: 1, col: 35 }, + end: Position { line: 1, col: 40 } + } }), ron::from_str::<BytesStruct>("BytesStruct( small:[1, 2], large:\"_+!!\" )"), ); @@ -55,7 +58,10 @@ fn v_9_deprecated_base64_bytes_support() { assert_eq!( Err(SpannedError { code: Error::Base64Error(base64::DecodeError::InvalidLastSymbol(1, b'x')), - position: Position { line: 1, col: 40 } + span: Span { + start: Position { line: 1, col: 35 }, + end: Position { line: 1, col: 40 } + } }), ron::from_str::<BytesStruct>("BytesStruct( small:[1, 2], large:\"/x==\" )"), ); @@ -64,7 +70,10 @@ fn v_9_deprecated_base64_bytes_support() { assert_eq!( Err(SpannedError { code: Error::Base64Error(base64::DecodeError::InvalidPadding), - position: Position { line: 1, col: 42 } + span: Span { + start: Position { line: 1, col: 35 }, + end: Position { line: 1, col: 42 } + } }), ron::from_str::<BytesStruct>("BytesStruct( small:[1, 2], large:\"AQIDBA\" )"), ); @@ -73,7 +82,10 @@ fn v_9_deprecated_base64_bytes_support() { assert_eq!( Err(SpannedError { code: Error::Base64Error(base64::DecodeError::InvalidByte(6, b'=')), - position: Position { line: 1, col: 45 } + span: Span { + start: Position { line: 1, col: 35 }, + end: Position { line: 1, col: 45 } + } }), ron::from_str::<BytesStruct>("BytesStruct( small:[1, 2], large:\"AQIDBA===\" )"), ); @@ -107,14 +119,20 @@ fn rusty_byte_string() { ron::from_str::<bytes::Bytes>("b\"\\xf\"").unwrap_err(), SpannedError { code: Error::InvalidEscape("Non-hex digit found"), - position: Position { line: 1, col: 7 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 7 }, + } }, ); assert_eq!( ron::from_str::<bytes::Bytes>("b\"\\xf🦀\"").unwrap_err(), SpannedError { code: Error::InvalidEscape("Non-hex digit found"), - position: Position { line: 1, col: 7 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 7 }, + } }, ); let err = ron::from_str::<bytes::Bytes>("br#q\"").unwrap_err(); @@ -122,7 +140,10 @@ fn rusty_byte_string() { err, SpannedError { code: Error::ExpectedByteString, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 4 }, + } }, ); assert_eq!(format!("{}", err.code), "Expected byte string",); @@ -130,21 +151,30 @@ fn rusty_byte_string() { ron::from_str::<bytes::Bytes>("br#\"q").unwrap_err(), SpannedError { code: Error::ExpectedStringEnd, - position: Position { line: 1, col: 5 }, + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 5 }, + } }, ); assert_eq!( ron::from_str::<String>("r#q\"").unwrap_err(), SpannedError { code: Error::ExpectedString, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 2 }, + end: Position { line: 1, col: 3 }, + } }, ); assert_eq!( ron::from_str::<String>("r#\"q").unwrap_err(), SpannedError { code: Error::ExpectedStringEnd, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 4 }, + } }, ); } @@ -306,7 +336,7 @@ fn serialize_backslash_byte_string() { } fn check_roundtrip< - T: PartialEq + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, + T: PartialEq + core::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, >( val: T, cmp: &str, @@ -352,35 +382,50 @@ fn test_weird_escapes() { ron::from_str::<String>(r#""\xf0""#), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 6 } + span: Span { + start: Position { line: 1, col: 2 }, + end: Position { line: 1, col: 6 } + } }) ); assert_eq!( ron::from_str::<String>(r#""\xf0\x9f""#), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 10 } + span: Span { + start: Position { line: 1, col: 6 }, + end: Position { line: 1, col: 10 } + } }) ); assert_eq!( ron::from_str::<String>(r#""\xf0\x9f\x40""#), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 14 } + span: Span { + start: Position { line: 1, col: 10 }, + end: Position { line: 1, col: 14 } + } }) ); assert_eq!( ron::from_str::<String>(r#""\xf0\x9f\xa6""#), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 14 } + span: Span { + start: Position { line: 1, col: 10 }, + end: Position { line: 1, col: 14 } + } }) ); assert_eq!( ron::from_str::<String>(r#""\xff\xff\xff\xff""#), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 18 } + span: Span { + start: Position { line: 1, col: 14 }, + end: Position { line: 1, col: 18 } + } }) ); @@ -389,7 +434,10 @@ fn test_weird_escapes() { ron::from_str::<char>(r"'\xf0\x9f\xa6\x80'"), Err(SpannedError { code: Error::InvalidEscape("Not a valid byte-escaped Unicode character"), - position: Position { line: 1, col: 6 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 6 } + } }) ); } @@ -430,7 +478,10 @@ fn byte_literal() { ron::from_str::<u8>(r#"b'\u{0}'"#), Err(SpannedError { code: Error::InvalidEscape("Unexpected Unicode escape in byte literal"), - position: Position { line: 1, col: 8 }, + span: Span { + start: Position { line: 1, col: 7 }, + end: Position { line: 1, col: 8 }, + } }) ); @@ -439,7 +490,10 @@ fn byte_literal() { err, SpannedError { code: Error::ExpectedByteLiteral, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 4 }, + } } ); assert_eq!(format!("{}", err.code), "Expected byte literal"); @@ -448,7 +502,10 @@ fn byte_literal() { ron::from_str::<u8>(r#"b'qq'"#).unwrap_err(), SpannedError { code: Error::ExpectedByteLiteral, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 4 }, + } } ); @@ -459,7 +516,10 @@ fn byte_literal() { expected: String::from("an 8-bit signed integer"), found: String::from(r#"b'9'"#) }, - position: Position { line: 1, col: 5 }, + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 5 }, + } }) ); } @@ -477,7 +537,10 @@ fn invalid_identifier() { ron::from_str::<Test>(&format!("({}: 42)", id)).unwrap_err(), SpannedError { code: Error::ExpectedIdentifier, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 2 }, + end: Position { line: 1, col: 2 }, + } } ); } diff --git a/third_party/rust/ron/tests/449_tagged_enum.rs b/third_party/rust/ron/tests/449_tagged_enum.rs @@ -43,16 +43,29 @@ enum OuterEnumUntagged { #[test] fn test_serde_content_hack() { - assert_eq!( + assert!(matches!( std::any::type_name::<serde::__private::de::Content>(), - "serde::__private::de::content::Content" - ); + "serde::__private::de::content::Content" | "serde::__private::de::content::Content<'_>" + )); } #[test] fn test_serde_internally_tagged_hack() { - const SERDE_CONTENT_CANARY: &str = "serde::__private::de::content::Content"; - const SERDE_TAG_KEY_CANARY: &str = "serde::__private::de::content::TagOrContent"; + // ensure that these are the same as in ron::de module + fn is_serde_content<T>() -> bool { + matches!( + core::any::type_name::<T>(), + "serde::__private::de::content::Content" | "serde::__private::de::content::Content<'_>" + ) + } + + fn is_serde_tag_or_content<T>() -> bool { + matches!( + core::any::type_name::<T>(), + "serde::__private::de::content::TagOrContent" + | "serde::__private::de::content::TagOrContent<'_>" + ) + } struct Deserializer { tag_key: Option<String>, @@ -87,7 +100,7 @@ fn test_serde_internally_tagged_hack() { where K: serde::de::DeserializeSeed<'de>, { - assert_eq!(std::any::type_name::<K::Value>(), SERDE_TAG_KEY_CANARY); + assert!(is_serde_tag_or_content::<K::Value>()); if let Some(tag_key) = self.tag_key.take() { return seed @@ -109,11 +122,11 @@ fn test_serde_internally_tagged_hack() { V: serde::de::DeserializeSeed<'de>, { if self.field_key.is_some() { - assert_ne!(std::any::type_name::<V::Value>(), SERDE_CONTENT_CANARY); + assert!(!is_serde_content::<V::Value>()); return seed.deserialize(serde::de::value::StrDeserializer::new(&self.tag_value)); } - assert_eq!(std::any::type_name::<V::Value>(), SERDE_CONTENT_CANARY); + assert!(is_serde_content::<V::Value>()); seed.deserialize(serde::de::value::I32Deserializer::new(self.field_value)) } diff --git a/third_party/rust/ron/tests/462_bytes.rs b/third_party/rust/ron/tests/462_bytes.rs @@ -16,7 +16,10 @@ fn test_deserialise_byte_slice() { expected: String::from("a borrowed byte array"), found: String::from("the byte string b\"\\x00\\x01\\x02\\x03\""), }, - position: ron::error::Position { line: 1, col: 10 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 9 }, + end: ron::error::Position { line: 1, col: 10 }, + } }) ); } diff --git a/third_party/rust/ron/tests/465_implicit_some_stack.rs b/third_party/rust/ron/tests/465_implicit_some_stack.rs @@ -9,7 +9,7 @@ fn roundtrip_implicit_some_stack() { } fn check_roundtrip< - T: PartialEq + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, + T: PartialEq + core::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, >( val: T, check: &str, diff --git a/third_party/rust/ron/tests/465_ser_backslash_string.rs b/third_party/rust/ron/tests/465_ser_backslash_string.rs @@ -5,7 +5,7 @@ fn serialize_backslash_string() { } fn check_roundtrip< - T: PartialEq + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, + T: PartialEq + core::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, >( val: T, cmp: &str, diff --git a/third_party/rust/ron/tests/465_unwrap_some_newtype_variant_value.rs b/third_party/rust/ron/tests/465_unwrap_some_newtype_variant_value.rs @@ -4,7 +4,10 @@ fn deserialise_value_with_unwrap_some_newtype_variant() { ron::from_str::<ron::Value>("Some(a: 42)"), Err(ron::error::SpannedError { code: ron::Error::ExpectedOptionEnd, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } }), ); assert_eq!( diff --git a/third_party/rust/ron/tests/481_number_underscores_suffixes.rs b/third_party/rust/ron/tests/481_number_underscores_suffixes.rs @@ -10,14 +10,21 @@ fn de_integer_underscores() { ron::from_str::<u8>("_0b1"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( ron::from_str::<u8>("_0b1_u8"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + // ? Start before end ? + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 6 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( @@ -27,7 +34,10 @@ fn de_integer_underscores() { digit: '2', base: 2 }, - position: ron::error::Position { line: 1, col: 3 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 3 }, + } }) ); assert_eq!( @@ -37,7 +47,10 @@ fn de_integer_underscores() { digit: '2', base: 2 }, - position: ron::error::Position { line: 1, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 4 }, + end: ron::error::Position { line: 1, col: 4 }, + } }) ); @@ -46,7 +59,10 @@ fn de_integer_underscores() { ron::from_str::<u8>("_0o5"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( @@ -56,7 +72,10 @@ fn de_integer_underscores() { digit: 'A', base: 8 }, - position: ron::error::Position { line: 1, col: 3 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 3 }, + } }) ); @@ -65,14 +84,20 @@ fn de_integer_underscores() { ron::from_str::<u8>("_0xF"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( ron::from_str::<u8>("0xZ"), Err(ron::error::SpannedError { code: ron::Error::ExpectedInteger, - position: ron::error::Position { line: 1, col: 3 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 3 }, + } }) ); @@ -81,7 +106,10 @@ fn de_integer_underscores() { ron::from_str::<u8>("_123"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( @@ -91,7 +119,10 @@ fn de_integer_underscores() { digit: 'a', base: 10 }, - position: ron::error::Position { line: 1, col: 3 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 3 }, + } }) ); } @@ -104,14 +135,20 @@ fn de_float_underscores() { ron::from_str::<f32>("_286"), Err(ron::error::SpannedError { code: ron::Error::UnderscoreAtBeginning, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); assert_eq!( ron::from_str::<f32>("2a86"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); @@ -120,7 +157,10 @@ fn de_float_underscores() { ron::from_str::<f32>("2_18__6_._"), Err(ron::error::SpannedError { code: ron::Error::FloatUnderscore, - position: ron::error::Position { line: 1, col: 10 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 10 }, + } }) ); assert_eq!( @@ -133,7 +173,10 @@ fn de_float_underscores() { ron::from_str::<f32>("._3__7_"), Err(ron::error::SpannedError { code: ron::Error::FloatUnderscore, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); @@ -145,7 +188,10 @@ fn de_float_underscores() { ron::from_str::<f64>("2_18__6_.3__7_e+____"), Err(ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } }) ); } @@ -191,7 +237,7 @@ fn check_number_roundtrip< + serde::Serialize + serde::de::DeserializeOwned + PartialEq - + std::fmt::Debug, + + core::fmt::Debug, >( n: T, suffix: &str, @@ -226,28 +272,40 @@ fn negative_unsigned() { ron::from_str::<ron::Value>("-1u8"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); assert_eq!( ron::from_str::<ron::Value>("-1u16"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); assert_eq!( ron::from_str::<ron::Value>("-1u32"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); assert_eq!( ron::from_str::<ron::Value>("-1u64"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); #[cfg(feature = "integer128")] @@ -255,7 +313,10 @@ fn negative_unsigned() { ron::from_str::<ron::Value>("-1u128"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 7 }, + } }) ); @@ -263,28 +324,40 @@ fn negative_unsigned() { ron::from_str::<u8>("-1u8"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); assert_eq!( ron::from_str::<u16>("-1u16"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); assert_eq!( ron::from_str::<u32>("-1u32"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); assert_eq!( ron::from_str::<u64>("-1u64"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 6 }, + } }) ); #[cfg(feature = "integer128")] @@ -292,7 +365,10 @@ fn negative_unsigned() { ron::from_str::<u128>("-1u128"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 7 }, + } }) ); } @@ -303,14 +379,20 @@ fn invalid_suffix() { ron::from_str::<ron::Value>("1u7"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); assert_eq!( ron::from_str::<ron::Value>("1f17"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); #[cfg(not(feature = "integer128"))] @@ -318,7 +400,10 @@ fn invalid_suffix() { ron::from_str::<ron::Value>("1u128"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); #[cfg(not(feature = "integer128"))] @@ -326,7 +411,10 @@ fn invalid_suffix() { ron::from_str::<ron::Value>("1i128"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); @@ -334,14 +422,20 @@ fn invalid_suffix() { ron::from_str::<u8>("1u7"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); assert_eq!( ron::from_str::<f32>("1f17"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); #[cfg(not(feature = "integer128"))] @@ -349,7 +443,10 @@ fn invalid_suffix() { ron::from_str::<u64>("1u128"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); #[cfg(not(feature = "integer128"))] @@ -357,7 +454,10 @@ fn invalid_suffix() { ron::from_str::<i64>("1i128"), Err(ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 2 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 2 }, + } }) ); } @@ -371,7 +471,10 @@ fn number_type_mismatch() { expected: String::from("an 8-bit unsigned integer"), found: String::from("1i32") }, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); @@ -379,7 +482,10 @@ fn number_type_mismatch() { ron::from_str::<i64>("-1u8"), Err(ron::error::SpannedError { code: ron::Error::IntegerOutOfBounds, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 3 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); @@ -390,7 +496,10 @@ fn number_type_mismatch() { expected: String::from("a 32-bit floating point number"), found: String::from("1f64") }, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); @@ -401,7 +510,10 @@ fn number_type_mismatch() { expected: String::from("a 64-bit floating point number"), found: String::from("1f32") }, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 2 }, + end: ron::error::Position { line: 1, col: 5 }, + } }) ); @@ -429,7 +541,7 @@ fn number_type_mismatch() { test_mismatch! { i128, u128 } } -fn check_number_type_mismatch<T: std::fmt::Debug + serde::de::DeserializeOwned>(suffix: &str) { +fn check_number_type_mismatch<T: core::fmt::Debug + serde::de::DeserializeOwned>(suffix: &str) { let ron = format!("0{suffix}"); if suffix.starts_with(std::any::type_name::<T>()) { @@ -442,7 +554,7 @@ fn check_number_type_mismatch<T: std::fmt::Debug + serde::de::DeserializeOwned>( println!("{:?} {}", err, suffix); assert_eq!( - err.position, + err.span.end, ron::error::Position { line: 1, col: 2 + suffix.len() @@ -460,7 +572,10 @@ fn float_const_prefix() { ron::from_str::<f32>("NaNf32a").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); @@ -468,7 +583,10 @@ fn float_const_prefix() { ron::from_str::<f64>("-inff64a").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); @@ -476,7 +594,10 @@ fn float_const_prefix() { ron::from_str::<f32>("+NaNf17").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); } @@ -487,21 +608,32 @@ fn invalid_float() { ron::from_str::<f32>("1ee3").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); assert_eq!( ron::from_str::<f32>("1ee3f32").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + // ? Start before end ? + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 5 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); assert_eq!( ron::from_str::<f64>("1ee3f64").unwrap_err(), ron::error::SpannedError { code: ron::Error::ExpectedFloat, - position: ron::error::Position { line: 1, col: 1 }, + // ? Start before end ? + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 5 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); } @@ -538,7 +670,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("true(false)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 5 }, + end: ron::error::Position { line: 1, col: 5 }, + } } ); @@ -548,7 +683,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("false(true)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 6 }, + end: ron::error::Position { line: 1, col: 6 }, + } } ); @@ -565,7 +703,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("None(true)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 5 }, + end: ron::error::Position { line: 1, col: 5 }, + } } ); @@ -575,7 +716,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("inf(false)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 4 }, + end: ron::error::Position { line: 1, col: 4 }, + } } ); @@ -591,7 +735,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("inff32(false)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } } ); @@ -607,7 +754,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("inff64(false)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } } ); @@ -617,7 +767,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("NaN(true)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 4 }, + end: ron::error::Position { line: 1, col: 4 }, + } } ); @@ -630,7 +783,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("NaNf32(true)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } } ); @@ -643,7 +799,10 @@ fn fuzzer_found_issues() { ron::from_str::<ron::Value>("NaNf64(true)").unwrap_err(), ron::error::SpannedError { code: ron::Error::TrailingCharacters, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } } ); } diff --git a/third_party/rust/ron/tests/492_enum_in_untagged_enum.rs b/third_party/rust/ron/tests/492_enum_in_untagged_enum.rs @@ -21,7 +21,7 @@ fn enum_in_untagged_enum() { ); } -fn check_roundtrip<T: Serialize + serde::de::DeserializeOwned + std::fmt::Debug + PartialEq>( +fn check_roundtrip<T: Serialize + serde::de::DeserializeOwned + core::fmt::Debug + PartialEq>( val: &T, check: &str, ) { diff --git a/third_party/rust/ron/tests/502_known_bugs.rs b/third_party/rust/ron/tests/502_known_bugs.rs @@ -1,6 +1,9 @@ use std::collections::{BTreeMap, HashMap}; -use ron::{error::Position, error::SpannedError, extensions::Extensions, ser::PrettyConfig, Error}; +use ron::{ + error::Position, error::Span, error::SpannedError, extensions::Extensions, ser::PrettyConfig, + Error, +}; use serde::{Deserialize, Serialize}; #[test] @@ -39,7 +42,10 @@ fn struct_names_inside_internally_tagged() { field: "hi", outer: None }, - position: Position { line: 7, col: 2 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 2 } + } })), ); } @@ -95,7 +101,10 @@ fn struct_names_inside_adjacently_tagged() { field: "ho", outer: Some(String::from("AdjacentlyTagged")) }, - position: Position { line: 1, col: 58 } + span: Span { + start: Position { line: 1, col: 58 }, + end: Position { line: 1, col: 58 } + } }), ); } @@ -135,7 +144,10 @@ fn struct_names_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 6, col: 2 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 2 } + } })), ); } @@ -182,7 +194,10 @@ fn struct_names_inside_flatten_struct() { field: "hi", outer: None }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })), ); } @@ -231,7 +246,10 @@ fn struct_names_inside_flatten_struct_variant() { field: "hi", outer: Some(String::from("C")) }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })), ); } @@ -459,7 +477,10 @@ fn implicit_some_inside_flatten_struct_variant() { expected: String::from("an empty array"), found: String::from("a unit value") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); assert_eq!( @@ -503,7 +524,10 @@ fn newtype_inside_internally_tagged() { expected: String::from("i32"), found: String::from("a sequence") }, - position: Position { line: 5, col: 2 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 2 } + } })) ); } @@ -537,7 +561,10 @@ fn newtype_inside_adjacently_tagged() { expected: String::from("i32"), found: String::from("a sequence") }, - position: Position { line: 1, col: 36 } + span: Span { + start: Position { line: 1, col: 36 }, + end: Position { line: 1, col: 36 } + } }) ); } @@ -559,7 +586,10 @@ fn newtype_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 4, col: 2 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 2 } + } })) ); } @@ -594,7 +624,10 @@ fn newtype_inside_flatten_struct() { expected: String::from("i32"), found: String::from("a sequence") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -631,7 +664,10 @@ fn newtype_inside_flatten_struct_variant() { expected: String::from("i32"), found: String::from("a sequence") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -672,7 +708,10 @@ fn one_tuple_inside_unwrapped_newtype_variant_inside_internally_tagged() { expected: String::from("a tuple of size 1"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 6, col: 2 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 2 } + } })) ); } @@ -728,7 +767,10 @@ fn one_tuple_inside_unwrapped_newtype_variant_inside_adjacently_tagged() { expected: String::from("an array of length 1"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 1, col: 79 } + span: Span { + start: Position { line: 1, col: 79 }, + end: Position { line: 1, col: 79 } + } }) ); } @@ -766,7 +808,10 @@ fn one_tuple_inside_unwrapped_newtype_variant_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 5, col: 2 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 2 } + } })) ); } @@ -817,7 +862,10 @@ fn one_tuple_inside_unwrapped_newtype_variant_inside_flatten_struct() { expected: String::from("an array of length 1"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -870,7 +918,10 @@ fn one_tuple_inside_unwrapped_newtype_variant_inside_flatten_struct_variant() { expected: String::from("a tuple of size 1"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -909,7 +960,10 @@ fn one_tuple_variant_inside_internally_tagged() { expected: String::from("tuple variant"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 7, col: 2 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 2 } + } })) ); } @@ -961,7 +1015,10 @@ fn one_tuple_variant_inside_adjacently_tagged() { expected: String::from("tuple variant"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 1, col: 50 } + span: Span { + start: Position { line: 1, col: 50 }, + end: Position { line: 1, col: 50 } + } }) ); } @@ -999,7 +1056,10 @@ fn one_tuple_variant_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 6, col: 2 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 2 } + } })) ); } @@ -1046,7 +1106,10 @@ fn one_tuple_variant_inside_flatten_struct() { expected: String::from("tuple variant"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1095,7 +1158,10 @@ fn one_tuple_variant_inside_flatten_struct_variant() { expected: String::from("tuple variant"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1129,7 +1195,10 @@ fn raw_value_inside_internally_tagged() { expected: String::from("any valid RON-value-string"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 7, col: 2 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 2 } + } })) ); } @@ -1178,7 +1247,10 @@ fn raw_value_inside_adjacently_tagged() { expected: String::from("any valid RON-value-string"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 1, col: 39 } + span: Span { + start: Position { line: 1, col: 39 }, + end: Position { line: 1, col: 39 } + } }) ); } @@ -1211,7 +1283,10 @@ fn raw_value_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 6, col: 2 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 2 } + } })) ); } @@ -1255,7 +1330,10 @@ fn raw_value_inside_flatten_struct() { expected: String::from("any valid RON-value-string"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1301,7 +1379,10 @@ fn raw_value_inside_flatten_struct_variant() { expected: String::from("any valid RON-value-string"), found: String::from("the unsigned integer `42`") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1332,7 +1413,10 @@ fn unit_like_zero_length_inside_internally_tagged() { expected: String::from("an empty array"), found: String::from("a unit value") }, - position: Position { line: 7, col: 2 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 2 } + } })) ); } @@ -1377,7 +1461,10 @@ fn unit_like_zero_length_inside_adjacently_tagged() { expected: String::from("tuple struct TupleStruct"), found: String::from("a unit value") }, - position: Position { line: 1, col: 40 } + span: Span { + start: Position { line: 1, col: 40 }, + end: Position { line: 1, col: 40 } + } }) ); } @@ -1410,7 +1497,10 @@ fn unit_like_zero_length_inside_untagged() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 6, col: 2 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 2 } + } })) ); } @@ -1454,7 +1544,10 @@ fn unit_like_zero_length_inside_flatten_struct() { expected: String::from("tuple variant"), found: String::from("a unit value") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1502,7 +1595,10 @@ fn unit_like_zero_length_inside_flatten_struct_variant() { expected: String::from("struct variant"), found: String::from("a unit value") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -1545,7 +1641,10 @@ fn i128_inside_internally_tagged() { expected: String::from("any value"), found: format!("integer `{}` as u128", i128::MAX) }, - position: Position { line: 5, col: 52 } + span: Span { + start: Position { line: 5, col: 13 }, + end: Position { line: 5, col: 52 } + } })) ); } @@ -1607,7 +1706,10 @@ fn u128_inside_adjacently_tagged() { expected: String::from("any value"), found: format!("integer `{}` as u128", u128::MAX) }, - position: Position { line: 1, col: 67 } + span: Span { + start: Position { line: 1, col: 28 }, + end: Position { line: 1, col: 67 } + } }), ); } @@ -1650,7 +1752,10 @@ fn i128_inside_untagged() { expected: String::from("any value"), found: format!("integer `{}` as i128", i128::MIN) }, - position: Position { line: 4, col: 53 } + span: Span { + start: Position { line: 4, col: 14 }, + end: Position { line: 4, col: 53 } + } })) ); } @@ -1703,7 +1808,10 @@ fn u128_inside_flatten_struct() { expected: String::from("any value"), found: format!("integer `{}` as u128", u128::MAX) }, - position: Position { line: 4, col: 52 } + span: Span { + start: Position { line: 4, col: 13 }, + end: Position { line: 4, col: 52 } + } })) ); } @@ -1758,7 +1866,10 @@ fn i128_inside_flatten_struct_variant() { expected: String::from("any value"), found: format!("integer `{}` as i128", i128::MIN) }, - position: Position { line: 4, col: 53 } + span: Span { + start: Position { line: 4, col: 14 }, + end: Position { line: 4, col: 53 } + } })) ); } @@ -1785,7 +1896,10 @@ fn duplicate_key_inside_flatten_struct() { field: "ho", outer: None }, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 3, col: 6 }, + end: Position { line: 3, col: 9 } + } })) ); } @@ -1828,7 +1942,10 @@ fn duplicate_key_inside_flatten_struct_variant() { field: "ho", outer: Some(String::from("A")) }, - position: Position { line: 3, col: 9 } + span: Span { + start: Position { line: 3, col: 6 }, + end: Position { line: 3, col: 9 } + } })) ); } @@ -1852,7 +1969,10 @@ fn non_string_key_inside_flatten_struct() { ), Err(Err(SpannedError { code: Error::ExpectedString, - position: Position { line: 3, col: 5 } + span: Span { + start: Position { line: 3, col: 5 }, + end: Position { line: 3, col: 5 } + } })) ); } @@ -1878,7 +1998,10 @@ fn non_string_key_inside_flatten_struct_variant() { ), Err(Err(SpannedError { code: Error::ExpectedString, - position: Position { line: 3, col: 5 } + span: Span { + start: Position { line: 3, col: 5 }, + end: Position { line: 3, col: 5 } + } })) ); } @@ -2008,7 +2131,10 @@ fn flatten_struct_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("a map") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -2056,7 +2182,10 @@ fn flatten_struct_beside_map_inside_flatten_struct_variant() { expected: String::from("i32"), found: String::from("a map") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -2163,7 +2292,10 @@ fn externally_tagged_newtype_variant_beside_map_inside_flatten_struct_variant() expected: String::from("i32"), found: String::from("a unit value") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -2198,7 +2330,10 @@ fn externally_tagged_struct_variant_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("a map") }, - position: Position { line: 6, col: 1 } + span: Span { + start: Position { line: 6, col: 1 }, + end: Position { line: 6, col: 1 } + } })) ); } @@ -2235,7 +2370,10 @@ fn externally_tagged_tuple_variant_beside_map_inside_flatten_struct_variant() { expected: String::from("i32"), found: String::from("a sequence") }, - position: Position { line: 7, col: 1 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 1 } + } })) ); } @@ -2271,7 +2409,10 @@ fn internally_tagged_unit_variant_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("the string \"Unit\"") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -2309,7 +2450,10 @@ fn internally_tagged_newtype_variant_beside_map_inside_flatten_struct_variant() expected: String::from("i32"), found: String::from("the string \"Newtype\"") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -2345,7 +2489,10 @@ fn internally_tagged_struct_variant_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("the string \"Struct\"") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2381,7 +2528,10 @@ fn adjacently_tagged_unit_variant_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("the string \"Unit\"") }, - position: Position { line: 4, col: 1 } + span: Span { + start: Position { line: 4, col: 1 }, + end: Position { line: 4, col: 1 } + } })) ); } @@ -2419,7 +2569,10 @@ fn adjacently_tagged_newtype_variant_beside_map_inside_flatten_struct_variant() expected: String::from("i32"), found: String::from("the string \"Newtype\"") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2455,7 +2608,10 @@ fn adjacently_tagged_struct_variant_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("the string \"Struct\"") }, - position: Position { line: 7, col: 1 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 1 } + } })) ); } @@ -2493,7 +2649,10 @@ fn adjacently_tagged_tuple_variant_beside_map_inside_flatten_struct_variant() { expected: String::from("i32"), found: String::from("the string \"Tuple\"") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2529,7 +2688,10 @@ fn tagged_struct_beside_map_inside_flatten_struct() { expected: String::from("i32"), found: String::from("the string \"Flattened\"") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2567,7 +2729,10 @@ fn tagged_struct_beside_map_inside_flatten_struct_variant() { expected: String::from("i32"), found: String::from("the string \"Flattened\"") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2586,7 +2751,10 @@ fn zero_length_untagged_tuple_variant() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 1, col: 3 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 } + } })) ); } @@ -2605,7 +2773,10 @@ fn zero_length_untagged_struct_variant() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 1, col: 3 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 } + } })) ); } @@ -2655,7 +2826,10 @@ fn unit_inside_untagged_newtype_variant_inside_internally_tagged_newtype_variant code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 3, col: 2 } + span: Span { + start: Position { line: 3, col: 1 }, + end: Position { line: 3, col: 2 } + } })) ); } @@ -2687,7 +2861,10 @@ fn unit_inside_untagged_newtype_variant_inside_flatten_struct() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 3, col: 1 } + span: Span { + start: Position { line: 3, col: 1 }, + end: Position { line: 3, col: 1 } + } })) ); } @@ -2718,7 +2895,10 @@ fn unit_struct_inside_untagged_newtype_variant_inside_internally_tagged_newtype_ code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 3, col: 2 } + span: Span { + start: Position { line: 3, col: 1 }, + end: Position { line: 3, col: 2 } + } })) ); } @@ -2752,7 +2932,10 @@ fn untagged_unit_variant_inside_internally_tagged_newtype_variant() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 3, col: 1 } + span: Span { + start: Position { line: 3, col: 1 }, + end: Position { line: 3, col: 1 } + } })) ); } @@ -2793,7 +2976,10 @@ fn untagged_unit_variant_inside_flatten_struct_variant() { code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 3, col: 2 } + span: Span { + start: Position { line: 3, col: 1 }, + end: Position { line: 3, col: 2 } + } })) ); } @@ -2834,7 +3020,10 @@ fn unit_inside_internally_tagged_newtype_variant_inside_multi_flatten_struct() { expected: String::from("unit"), found: String::from("a map") }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2880,7 +3069,10 @@ fn untagged_unit_variant_inside_internally_tagged_newtype_variant_inside_multi_f code: Error::Message(String::from( "data did not match any variant of untagged enum Untagged" )), - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2920,7 +3112,10 @@ fn flattened_externally_tagged_newtype_variant_beside_flattened_intenally_tagged expected: String::from("map with a single key"), found: String::from("a map"), }, - position: Position { line: 5, col: 1 } + span: Span { + start: Position { line: 5, col: 1 }, + end: Position { line: 5, col: 1 } + } })) ); } @@ -2960,7 +3155,10 @@ fn flattened_externally_tagged_struct_variant_beside_flattened_intenally_tagged_ expected: String::from("map with a single key"), found: String::from("a map"), }, - position: Position { line: 7, col: 1 } + span: Span { + start: Position { line: 7, col: 1 }, + end: Position { line: 7, col: 1 } + } })) ); } @@ -3060,7 +3258,7 @@ fn flattened_field_inside_flattened_struct_alongside_map() { ); } -fn check_roundtrip<T: PartialEq + std::fmt::Debug + Serialize + serde::de::DeserializeOwned>( +fn check_roundtrip<T: PartialEq + core::fmt::Debug + Serialize + serde::de::DeserializeOwned>( val: &T, config: PrettyConfig, ) -> Result<(), Result<Error, SpannedError>> { diff --git a/third_party/rust/ron/tests/508_value_adjacently_tagged_bug.rs b/third_party/rust/ron/tests/508_value_adjacently_tagged_bug.rs @@ -36,7 +36,10 @@ fn roundtrip_through_value() { err, ron::error::SpannedError { code: ron::Error::ExpectedIdentifier, - position: ron::error::Position { line: 1, col: 7 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 7 }, + end: ron::error::Position { line: 1, col: 7 }, + } } ); diff --git a/third_party/rust/ron/tests/511_deserialize_any_map_string_key.rs b/third_party/rust/ron/tests/511_deserialize_any_map_string_key.rs @@ -17,7 +17,7 @@ fn test_map_custom_deserialize() { type Value = CustomMap; // GRCOV_EXCL_START - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { write!(formatter, "a map with string keys and values") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/tests/564_exhaustive_number.rs b/third_party/rust/ron/tests/564_exhaustive_number.rs @@ -0,0 +1,40 @@ +use ron::Number; + +#[test] +fn exhaustive_number_match() { + match Number::U8(42) { + Number::I8(v) => println!("{v}"), + Number::I16(v) => println!("{v}"), + Number::I32(v) => println!("{v}"), + Number::I64(v) => println!("{v}"), + #[cfg(feature = "integer128")] + Number::I128(v) => println!("{v}"), + Number::U8(v) => println!("{v}"), + Number::U16(v) => println!("{v}"), + Number::U32(v) => println!("{v}"), + Number::U64(v) => println!("{v}"), + #[cfg(feature = "integer128")] + Number::U128(v) => println!("{v}"), + Number::F32(v) => println!("{}", v.0), + Number::F64(v) => println!("{}", v.0), + #[cfg(not(doc))] + Number::__NonExhaustive(never) => never.never(), + } +} + +#[test] +fn non_exhaustive_number_match() { + match Number::U8(42) { + Number::I8(v) => println!("{v}"), + Number::I16(v) => println!("{v}"), + Number::I32(v) => println!("{v}"), + Number::I64(v) => println!("{v}"), + Number::U8(v) => println!("{v}"), + Number::U16(v) => println!("{v}"), + Number::U32(v) => println!("{v}"), + Number::U64(v) => println!("{v}"), + Number::F32(v) => println!("{}", v.0), + Number::F64(v) => println!("{}", v.0), + v => println!("{v:?}"), + } +} diff --git a/third_party/rust/ron/tests/comments.rs b/third_party/rust/ron/tests/comments.rs @@ -1,4 +1,4 @@ -use ron::de::{from_str, Error, Position, SpannedError as RonErr}; +use ron::de::{from_str, Error, Position, Span, SpannedError as RonErr}; #[test] fn test_simple() { @@ -36,7 +36,10 @@ fn test_unclosed() { from_str::<String>("\"hi\" /*"), Err(RonErr { code: Error::UnclosedBlockComment, - position: Position { line: 1, col: 8 } + span: Span { + start: Position { line: 1, col: 6 }, + end: Position { line: 1, col: 8 } + } }) ); assert_eq!( @@ -53,7 +56,10 @@ fn test_unclosed() { ), Err(RonErr { code: Error::UnclosedBlockComment, - position: Position { line: 9, col: 1 } + span: Span { + start: Position { line: 7, col: 3 }, + end: Position { line: 9, col: 1 } + } }) ); } @@ -64,7 +70,10 @@ fn test_unexpected_byte() { from_str::<u8>("42 /q"), Err(RonErr { code: Error::UnexpectedChar('q'), - position: Position { line: 1, col: 6 }, + span: Span { + start: Position { line: 1, col: 4 }, + end: Position { line: 1, col: 6 }, + } }) ); } diff --git a/third_party/rust/ron/tests/escape.rs b/third_party/rust/ron/tests/escape.rs @@ -17,7 +17,10 @@ fn test_escape_basic() { from_str::<char>("\'\\u{}\'").unwrap_err(), ron::error::SpannedError { code: ron::Error::InvalidEscape("Expected 1-6 digits, got 0 digits in Unicode escape"), - position: ron::error::Position { line: 1, col: 5 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 4 }, + end: ron::error::Position { line: 1, col: 5 }, + } } ); @@ -25,7 +28,10 @@ fn test_escape_basic() { from_str::<char>("\'\\q\'").unwrap_err(), ron::error::SpannedError { code: ron::Error::InvalidEscape("Unknown escape character"), - position: ron::error::Position { line: 1, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 4 }, + } } ) } diff --git a/third_party/rust/ron/tests/non_identifier_identifier.rs b/third_party/rust/ron/tests/non_identifier_identifier.rs @@ -10,7 +10,7 @@ macro_rules! test_non_identifier { type Value = FieldName; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("an error") } // GRCOV_EXCL_STOP @@ -32,7 +32,7 @@ macro_rules! test_non_identifier { type Value = Struct; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a struct") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/tests/non_string_tag.rs b/third_party/rust/ron/tests/non_string_tag.rs @@ -10,7 +10,7 @@ macro_rules! test_non_tag { type Value = Tag; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("an error") } // GRCOV_EXCL_STOP @@ -91,7 +91,7 @@ macro_rules! test_tag { type Value = Tag; // GRCOV_EXCL_START - fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { fmt.write_str("a tag") } // GRCOV_EXCL_STOP diff --git a/third_party/rust/ron/tests/numbers.rs b/third_party/rust/ron/tests/numbers.rs @@ -1,6 +1,6 @@ use ron::{ de::from_str, - error::{Error, Position, SpannedError}, + error::{Error, Position, Span, SpannedError}, }; #[test] @@ -13,21 +13,30 @@ fn test_hex() { from_str::<u8>("0x"), Err(SpannedError { code: Error::ExpectedInteger, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0x_1"), Err(SpannedError { code: Error::UnderscoreAtBeginning, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0xFFF"), Err(SpannedError { code: Error::IntegerOutOfBounds, - position: Position { line: 1, col: 6 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 6 }, + } }) ); } @@ -42,21 +51,30 @@ fn test_bin() { from_str::<u8>("0b"), Err(SpannedError { code: Error::ExpectedInteger, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0b_1"), Err(SpannedError { code: Error::UnderscoreAtBeginning, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0b111111111"), Err(SpannedError { code: Error::IntegerOutOfBounds, - position: Position { line: 1, col: 12 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 12 }, + } }) ); } @@ -71,21 +89,30 @@ fn test_oct() { from_str::<u8>("0o"), Err(SpannedError { code: Error::ExpectedInteger, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0o_1"), Err(SpannedError { code: Error::UnderscoreAtBeginning, - position: Position { line: 1, col: 3 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 3 }, + } }) ); assert_eq!( from_str::<u8>("0o77777"), Err(SpannedError { code: Error::IntegerOutOfBounds, - position: Position { line: 1, col: 8 }, + span: Span { + start: Position { line: 1, col: 3 }, + end: Position { line: 1, col: 8 }, + } }) ); } @@ -100,14 +127,20 @@ fn test_dec() { from_str::<i8>("-_1"), Err(SpannedError { code: Error::UnderscoreAtBeginning, - position: Position { line: 1, col: 2 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 2 }, + } }) ); assert_eq!( from_str::<u8>("256"), Err(SpannedError { code: Error::IntegerOutOfBounds, - position: Position { line: 1, col: 4 }, + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { line: 1, col: 4 }, + } }) ); } diff --git a/third_party/rust/ron/tests/options.rs b/third_party/rust/ron/tests/options.rs @@ -64,6 +64,7 @@ fn single_default_extension() { assert_eq!(ser, "#![enable(unwrap_newtypes)]\n(42, 4.2)"); } +#[cfg(feature = "std")] #[test] fn reader_io_error() { struct Reader<'a> { @@ -85,14 +86,20 @@ fn reader_io_error() { ron::de::from_reader::<Reader, ()>(Reader { buf: b"" }).unwrap_err(), ron::error::SpannedError { code: ron::Error::Io(String::from("oh no")), - position: ron::error::Position { line: 1, col: 1 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 1 }, + } } ); assert_eq!( ron::de::from_reader::<Reader, ()>(Reader { buf: b"hello" }).unwrap_err(), ron::error::SpannedError { code: ron::Error::Io(String::from("oh no")), - position: ron::error::Position { line: 1, col: 6 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 1, col: 6 }, + } } ); assert_eq!( @@ -102,7 +109,10 @@ fn reader_io_error() { .unwrap_err(), ron::error::SpannedError { code: ron::Error::Io(String::from("oh no")), - position: ron::error::Position { line: 2, col: 4 }, + span: ron::error::Span { + start: ron::error::Position { line: 1, col: 1 }, + end: ron::error::Position { line: 2, col: 4 }, + } } ); } diff --git a/third_party/rust/ron/tests/unicode.rs b/third_party/rust/ron/tests/unicode.rs @@ -30,10 +30,10 @@ fn ident_starts_with_non_ascii_byte() { fn test_file_invalid_unicode() { let error = from_bytes::<Value>(&[b'\n', b'a', 0b11000000, 0]).unwrap_err(); assert!(matches!(error.code, Error::Utf8Error(_))); - assert_eq!(error.position, Position { line: 2, col: 2 }); + assert_eq!(error.span.end, Position { line: 2, col: 2 }); let error = from_bytes::<Value>(&[b'\n', b'\n', 0b11000000]).unwrap_err(); assert!(matches!(error.code, Error::Utf8Error(_))); - assert_eq!(error.position, Position { line: 3, col: 1 }); + assert_eq!(error.span.end, Position { line: 3, col: 1 }); } #[test] diff --git a/third_party/rust/ron/tests/value.rs b/third_party/rust/ron/tests/value.rs @@ -149,7 +149,7 @@ fn seq() { #[test] fn unit() { - use ron::error::{Error, Position, SpannedError}; + use ron::error::{Position, Span, SpannedError}; assert_eq!("()".parse(), Ok(Value::Unit)); assert_eq!("Foo".parse(), Ok(Value::Unit)); @@ -158,7 +158,10 @@ fn unit() { "".parse::<Value>(), Err(SpannedError { code: Error::Eof, - position: Position { col: 1, line: 1 } + span: Span { + start: Position { line: 1, col: 1 }, + end: Position { col: 1, line: 1 } + } }) ); diff --git a/third_party/rust/wgpu-core/.cargo-checksum.json b/third_party/rust/wgpu-core/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"8f1c92b825fa1e2bc1e95e0101a962a1106e3ed3ed1d79f5cb08f6af1d1dd943","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"5e3619e28faeac243cbae1a5f739ad15035dc9e1254957b64fd1deed6f393c8a","src/as_hal.rs":"473936fe2c26563f9fea71bbafdb7eb3d8ff5f4fe9376052d18db3ea8e2908ff","src/binding_model.rs":"9943f0814b697f446ee374343a980e49ca2f8fae1bb1955ba889eb0bee4b1f3b","src/command/allocator.rs":"386cb6e60bd332a881dbbe57ff66a0fa83f35e3ee924559f1689418ac6c7273a","src/command/bind.rs":"c88aa87bf3052fe0993b79ff047339fac4557ead85973f4a37bf236fba401222","src/command/bundle.rs":"d078bb708cbdea42ebebc5c5a510bff3cad982b67be3682ed5956bfb212114f1","src/command/clear.rs":"faeea4c8c9101bb94738898d5a897efe9fba785139b619810482f3a56a697169","src/command/compute.rs":"d1028894d756e57084f41b2fe145d462286428520edd527ce47fb9730f84456a","src/command/compute_command.rs":"18aa0b8e389a5d345243b876b1abbacfc998a19d23069e092183fa7be10fa0ab","src/command/draw.rs":"e7bf195d33683a19b077e64d181cb27b8acde724732ac9af3c94d83c3f21559e","src/command/encoder.rs":"8a50538d3bcea0dc32667511fa100ccafb428c24731a7aa92bb8cfbaf716f93e","src/command/encoder_command.rs":"ec4706662be3faed796cc96c18f1722f859b618aa42cf75f22c3674499cf458e","src/command/ffi.rs":"1fb626579a7726a32d571a17a14f2656def0c170f4f6297e7e51772a6fc5a566","src/command/memory_init.rs":"f68a796c4262d261620cf85e5762e267dee013f4ef5d61f67fcb173b59048983","src/command/mod.rs":"4af2aa3fa03b04690a0a0068e68d0e92bfc0104e8030a59243ffd5bcd0b569c2","src/command/pass.rs":"be6fb0848cf4a4eae0a08811bfaf96743d1a49c0929e75455aaf78077b18a58c","src/command/query.rs":"d539711f388e4c632dbe245e88f4b394daa5f3ddca7b8a6e1ac232609ea67123","src/command/ray_tracing.rs":"7db2d2df3405d37725fcaef652f2730b1f8d8214916516241599661a0d1e498a","src/command/render.rs":"3ffd48945856fce24489527eb308d02e40b8f6b24fc430e06bce2a0764529422","src/command/render_command.rs":"3f1bc2fec688fa3f33052867eeb2e194020a643f7d16f6111b8b128594c38570","src/command/timestamp_writes.rs":"da06fb07b8d0917be3e7fb9212d0ffc6b16526e1c1df617213ef354c3e1fb446","src/command/transfer.rs":"b5836a72051f51d1c0aea97b0c7c79893a332d1e40c2e5e1f865b7349dc06ba1","src/command/transition_resources.rs":"56bd73c59cf554fda3eb22d7d7d02e19951ffc01bbc68c6413c8b65fe03d1d5e","src/conv.rs":"c3354002c8c69994692c923d3772744a0f634b760ca73d79634041190d06453a","src/device/bgl.rs":"fcb1d53b692970912781748379df675268981c97352872abf2e7bb0b1ebdd533","src/device/global.rs":"234b463b95382909ce9b514464d4618a38229751ddd3cb9caca4176b89b44a5b","src/device/life.rs":"44bd34cf5ab1c1a21729f2188df6d2ca0238f11c5f723380c8a4a16fbbd90b88","src/device/mod.rs":"729d9aeddb9c2bbc134e495526b9923c03e11cbb06055e0d3f81e36b20c874da","src/device/queue.rs":"e4d93d857cb7cf1d43365d73d0711ebdbedcf4052b72135fc203bb5a8197ef3a","src/device/ray_tracing.rs":"cb13bc0caf54113ca12ce5db147af339474ec4b2423f2556600b5ea936b408cc","src/device/resource.rs":"6c45f76cad7ea4b43c5dde578a4b3eb6e85626db9d4430d62b3798927e88b657","src/device/trace.rs":"39e52ee5b220eb6a13d949582f1f87756189648bf2f05ea7148b0a67b73c226f","src/error.rs":"4f07a0b09b30b2d6cbc855d0091d724000f492018af3b41e80befbeccf2a6f4e","src/global.rs":"bd76f9552496996f9eba6502e5caf1bcd6ca33bf3d5008795b5335f74e56fd55","src/hash_utils.rs":"9f57a627fe3f00659391670141df62f68d67922c7b186f2a9a5958ab16fb576f","src/hub.rs":"308c53e05134e5a48294c61511e43077adfdb5c334237de2016ed4537d562382","src/id.rs":"134974aa304d1d0eb7349438b9660519886c513f01d5868cd4331d2bc78f2cb8","src/identity.rs":"712ccda267eb602655c53672a94346aa4c9f88c0044ae6edcd658a814c9a50cf","src/indirect_validation/dispatch.rs":"b15d926e0de732c3c39c965f168f99598fa508ca4b0883061993d99dd644b31a","src/indirect_validation/draw.rs":"6d8338f37f406c6e2cf89713e8493f167e1d8e999737f2976de298810c2ada76","src/indirect_validation/mod.rs":"79466e4f9a59386e833958b3537beed6ffb6a7ee62aaabcf35382c2683998e43","src/indirect_validation/utils.rs":"e6a3b636dd71ff6b01d5abd5a589a0136fb30aa1d517a43f45cf2e5ad54da245","src/indirect_validation/validate_draw.wgsl":"fa7bba5f28c6c181f2d55ecfe386a5e5cd276bcb3c36aa7f963f43c535a9bf9a","src/init_tracker/buffer.rs":"6167a400ab271ba857f1c507e60a46fbd318c185aff87eecf7eb05f7f09b6963","src/init_tracker/mod.rs":"aa87df3428e3b23507377c71eae92dc1dd9f5d5374aa0b03906fb81507fc6ce6","src/init_tracker/texture.rs":"ffdc67d4be23bcd48b22945de94ac0ea8ee571f91eb6d00323b9afe6fa91eef3","src/instance.rs":"ea7f8e9e1dff27c19e6ddfd0842d001e057e2cb856b1ec1443ab717ac13de276","src/lib.rs":"b5f2a8cf9e37476f9730e0dfc0b55160114d0c969620105bad732e3f374bf9eb","src/lock/mod.rs":"8d3ae3f8d004d7f7d8a3aefe9f30b35669cb8e2409f5fba27b1fcb116b2429c4","src/lock/observing.rs":"f2df071927940e34e808d718c890caea0c3b70c56c2499c98efbddc052eda46f","src/lock/rank.rs":"238e6a97c58ee1a804863c8011bb257864301170344d18596bdaab09f3f74b54","src/lock/ranked.rs":"a95d6bf7f2ef510047a4c33687076beccf38a0148aac3261bd29fa7555e3f488","src/lock/vanilla.rs":"ca8156d4c981473d437db1056487a44c714760d685819eaff8cf82fb0098a608","src/pipeline.rs":"b7aae46522bc6843b0f47dac7e73e33197c76e9724cfb4be3b949bfa27a99fb1","src/pipeline_cache.rs":"256bf8df58d8ab904afddc132349d03e4f659b6bd6882bc8df582dcfd05ae3d5","src/pool.rs":"e11bfdc73a66321d26715465fa74657dcd26a9b856b80b8369b4aac2132a4295","src/present.rs":"bf0c6c47e58496199955013170f41cbf10755c1572583d5af4b88686c28ffb66","src/ray_tracing.rs":"6e33799815e98d0dc7e98902e6b9c9c928bc50aaab27f343379989a13cc728f9","src/registry.rs":"ecd457e8956e065050bb9c63ca404505e56ffed6d540b3f14f745d7c4010b205","src/resource.rs":"729534761eccf965758ed82a21c7ffd357d7378c9216b25d0649185ce714b8b2","src/scratch.rs":"ea5c40e4d18a12f09cc1038f2dcdddb69b13e99275ac987d826658229a39b326","src/snatch.rs":"bf422810afd952894e365cd397763d42d6365ce3c5a5b4c1170566432f462939","src/storage.rs":"29427dea035d03abc8b8abdebecc5591378f1366088d1468ab2beb8536e7d675","src/timestamp_normalization/common.wgsl":"9f65aef0526ff9dde945fae70cef064ad961b0aee4291759ae82974cd2ead0a7","src/timestamp_normalization/mod.rs":"89444ad79900c12c2dc44780f1525cd0554d6ed1d9038938dd0075e8173ae59d","src/timestamp_normalization/timestamp_normalization.wgsl":"4b2202b965e4c67482d03a546ac38c72a602d79ed9a60e6f7217393c49afad49","src/track/blas.rs":"18c7b5b89a60ab49bbc0f4f8b85a24502c1d968714ef4c586095e119848d902a","src/track/buffer.rs":"1ab5310367606fc74f0791733ea5ba2e09acc92ff7f4f4773f66bcfb3138c52f","src/track/metadata.rs":"04b8bcf8ded7c7c805d9336cfc874da9d8de7d12d99f7525f0540780a1dffc45","src/track/mod.rs":"a66ce12a4dc430a63bd6a3e05818695e407cfb079b320a5cd000bd1b45ceb6a3","src/track/range.rs":"2688b05a0c6e8510ff6ba3a9623e8b83f433a05ba743129928c56c93d9a9c233","src/track/stateless.rs":"3db699f5f48a319fa07fb16cdf51e1623d6ecac7a476467ee366e014ea665b89","src/track/texture.rs":"754c54f3051c8c780f3904c8c9213fc91ea1838ee14301731dd069a98c8c6695","src/validation.rs":"39a38eb27487d1510d883253539c68a45ecb1cfb8f2afb65ac065b84108b7b55","src/weak_vec.rs":"a4193add5912b91226a3155cc613365b7fafdf2e7929d21d68bc19d149696e85"},"package":null} -\ No newline at end of file +{"files":{"Cargo.toml":"aece940ca117dac54de0c9eaa557f82ee2b200e11741c798256711dd96837dd3","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","build.rs":"5e3619e28faeac243cbae1a5f739ad15035dc9e1254957b64fd1deed6f393c8a","src/as_hal.rs":"473936fe2c26563f9fea71bbafdb7eb3d8ff5f4fe9376052d18db3ea8e2908ff","src/binding_model.rs":"9943f0814b697f446ee374343a980e49ca2f8fae1bb1955ba889eb0bee4b1f3b","src/command/allocator.rs":"386cb6e60bd332a881dbbe57ff66a0fa83f35e3ee924559f1689418ac6c7273a","src/command/bind.rs":"c88aa87bf3052fe0993b79ff047339fac4557ead85973f4a37bf236fba401222","src/command/bundle.rs":"d078bb708cbdea42ebebc5c5a510bff3cad982b67be3682ed5956bfb212114f1","src/command/clear.rs":"932afc6e1858f8c93d3ecf721215a0bc584a8e613444641a98f5cb98e3061b4b","src/command/compute.rs":"3c2d8e6cf2ff53c94f7d25f42d1a74ea656ea6122f8022d90d0f43b0f82a29ed","src/command/compute_command.rs":"18aa0b8e389a5d345243b876b1abbacfc998a19d23069e092183fa7be10fa0ab","src/command/draw.rs":"e7bf195d33683a19b077e64d181cb27b8acde724732ac9af3c94d83c3f21559e","src/command/encoder.rs":"7655f8c248120f39e37f3ad0f84bd9816df78a75657790ab12d5aba144fef65f","src/command/encoder_command.rs":"4e1d28040d9330a803644e377bd7675ec503cd0396c31394658dc67d71a4b50f","src/command/ffi.rs":"1fb626579a7726a32d571a17a14f2656def0c170f4f6297e7e51772a6fc5a566","src/command/memory_init.rs":"f68a796c4262d261620cf85e5762e267dee013f4ef5d61f67fcb173b59048983","src/command/mod.rs":"8fa942354820b79c78040e4da0fd6e7f4423486f691f4545490c79857904f106","src/command/pass.rs":"5ee6e7a68329b716b5a5231b27794682b5b17a6ee2c237f658bb9b71dd2efeca","src/command/query.rs":"fa7cb51fbbaa50febe0e61c473891d4131125c290180a05d49b60f5138931fb4","src/command/ray_tracing.rs":"4768a6dba5f737d3550a90ca35fe75c39fe241fc2d41c3795eb329139c5e6ec6","src/command/render.rs":"4a5409a4ffe48252bd44061c96baa948cc8cd13912e2cc5dec6e40c8d7c259b6","src/command/render_command.rs":"3f1bc2fec688fa3f33052867eeb2e194020a643f7d16f6111b8b128594c38570","src/command/timestamp_writes.rs":"da06fb07b8d0917be3e7fb9212d0ffc6b16526e1c1df617213ef354c3e1fb446","src/command/transfer.rs":"28fdca903934d7e2e5d12d28f952ad3e9ef804c8452f9d020831b5e6aca7e19d","src/command/transition_resources.rs":"753cb02adfee4758404c403d19fd76e6c8de77de01435a2cbe2f60bdbe44bde1","src/conv.rs":"c3354002c8c69994692c923d3772744a0f634b760ca73d79634041190d06453a","src/device/bgl.rs":"fcb1d53b692970912781748379df675268981c97352872abf2e7bb0b1ebdd533","src/device/global.rs":"234b463b95382909ce9b514464d4618a38229751ddd3cb9caca4176b89b44a5b","src/device/life.rs":"44bd34cf5ab1c1a21729f2188df6d2ca0238f11c5f723380c8a4a16fbbd90b88","src/device/mod.rs":"729d9aeddb9c2bbc134e495526b9923c03e11cbb06055e0d3f81e36b20c874da","src/device/queue.rs":"e4d93d857cb7cf1d43365d73d0711ebdbedcf4052b72135fc203bb5a8197ef3a","src/device/ray_tracing.rs":"cb13bc0caf54113ca12ce5db147af339474ec4b2423f2556600b5ea936b408cc","src/device/resource.rs":"6c45f76cad7ea4b43c5dde578a4b3eb6e85626db9d4430d62b3798927e88b657","src/device/trace.rs":"39e52ee5b220eb6a13d949582f1f87756189648bf2f05ea7148b0a67b73c226f","src/error.rs":"4f07a0b09b30b2d6cbc855d0091d724000f492018af3b41e80befbeccf2a6f4e","src/global.rs":"bd76f9552496996f9eba6502e5caf1bcd6ca33bf3d5008795b5335f74e56fd55","src/hash_utils.rs":"9f57a627fe3f00659391670141df62f68d67922c7b186f2a9a5958ab16fb576f","src/hub.rs":"308c53e05134e5a48294c61511e43077adfdb5c334237de2016ed4537d562382","src/id.rs":"134974aa304d1d0eb7349438b9660519886c513f01d5868cd4331d2bc78f2cb8","src/identity.rs":"712ccda267eb602655c53672a94346aa4c9f88c0044ae6edcd658a814c9a50cf","src/indirect_validation/dispatch.rs":"b15d926e0de732c3c39c965f168f99598fa508ca4b0883061993d99dd644b31a","src/indirect_validation/draw.rs":"6d8338f37f406c6e2cf89713e8493f167e1d8e999737f2976de298810c2ada76","src/indirect_validation/mod.rs":"79466e4f9a59386e833958b3537beed6ffb6a7ee62aaabcf35382c2683998e43","src/indirect_validation/utils.rs":"e6a3b636dd71ff6b01d5abd5a589a0136fb30aa1d517a43f45cf2e5ad54da245","src/indirect_validation/validate_draw.wgsl":"fa7bba5f28c6c181f2d55ecfe386a5e5cd276bcb3c36aa7f963f43c535a9bf9a","src/init_tracker/buffer.rs":"6167a400ab271ba857f1c507e60a46fbd318c185aff87eecf7eb05f7f09b6963","src/init_tracker/mod.rs":"aa87df3428e3b23507377c71eae92dc1dd9f5d5374aa0b03906fb81507fc6ce6","src/init_tracker/texture.rs":"ffdc67d4be23bcd48b22945de94ac0ea8ee571f91eb6d00323b9afe6fa91eef3","src/instance.rs":"ea7f8e9e1dff27c19e6ddfd0842d001e057e2cb856b1ec1443ab717ac13de276","src/lib.rs":"b5f2a8cf9e37476f9730e0dfc0b55160114d0c969620105bad732e3f374bf9eb","src/lock/mod.rs":"8d3ae3f8d004d7f7d8a3aefe9f30b35669cb8e2409f5fba27b1fcb116b2429c4","src/lock/observing.rs":"f2df071927940e34e808d718c890caea0c3b70c56c2499c98efbddc052eda46f","src/lock/rank.rs":"238e6a97c58ee1a804863c8011bb257864301170344d18596bdaab09f3f74b54","src/lock/ranked.rs":"a95d6bf7f2ef510047a4c33687076beccf38a0148aac3261bd29fa7555e3f488","src/lock/vanilla.rs":"ca8156d4c981473d437db1056487a44c714760d685819eaff8cf82fb0098a608","src/pipeline.rs":"b7aae46522bc6843b0f47dac7e73e33197c76e9724cfb4be3b949bfa27a99fb1","src/pipeline_cache.rs":"256bf8df58d8ab904afddc132349d03e4f659b6bd6882bc8df582dcfd05ae3d5","src/pool.rs":"e11bfdc73a66321d26715465fa74657dcd26a9b856b80b8369b4aac2132a4295","src/present.rs":"bf0c6c47e58496199955013170f41cbf10755c1572583d5af4b88686c28ffb66","src/ray_tracing.rs":"a4261ccd978e8fab1fef48a168d2d33f8a9f2dae89f285ecd9ec8a6d0894fa3b","src/registry.rs":"ecd457e8956e065050bb9c63ca404505e56ffed6d540b3f14f745d7c4010b205","src/resource.rs":"729534761eccf965758ed82a21c7ffd357d7378c9216b25d0649185ce714b8b2","src/scratch.rs":"ea5c40e4d18a12f09cc1038f2dcdddb69b13e99275ac987d826658229a39b326","src/snatch.rs":"bf422810afd952894e365cd397763d42d6365ce3c5a5b4c1170566432f462939","src/storage.rs":"29427dea035d03abc8b8abdebecc5591378f1366088d1468ab2beb8536e7d675","src/timestamp_normalization/common.wgsl":"9f65aef0526ff9dde945fae70cef064ad961b0aee4291759ae82974cd2ead0a7","src/timestamp_normalization/mod.rs":"89444ad79900c12c2dc44780f1525cd0554d6ed1d9038938dd0075e8173ae59d","src/timestamp_normalization/timestamp_normalization.wgsl":"4b2202b965e4c67482d03a546ac38c72a602d79ed9a60e6f7217393c49afad49","src/track/blas.rs":"18c7b5b89a60ab49bbc0f4f8b85a24502c1d968714ef4c586095e119848d902a","src/track/buffer.rs":"1ab5310367606fc74f0791733ea5ba2e09acc92ff7f4f4773f66bcfb3138c52f","src/track/metadata.rs":"04b8bcf8ded7c7c805d9336cfc874da9d8de7d12d99f7525f0540780a1dffc45","src/track/mod.rs":"a66ce12a4dc430a63bd6a3e05818695e407cfb079b320a5cd000bd1b45ceb6a3","src/track/range.rs":"2688b05a0c6e8510ff6ba3a9623e8b83f433a05ba743129928c56c93d9a9c233","src/track/stateless.rs":"3db699f5f48a319fa07fb16cdf51e1623d6ecac7a476467ee366e014ea665b89","src/track/texture.rs":"754c54f3051c8c780f3904c8c9213fc91ea1838ee14301731dd069a98c8c6695","src/validation.rs":"39a38eb27487d1510d883253539c68a45ecb1cfb8f2afb65ac065b84108b7b55","src/weak_vec.rs":"a4193add5912b91226a3155cc613365b7fafdf2e7929d21d68bc19d149696e85"},"package":null} +\ No newline at end of file diff --git a/third_party/rust/wgpu-core/Cargo.toml b/third_party/rust/wgpu-core/Cargo.toml @@ -129,7 +129,7 @@ features = [ version = "0.2.10" [dependencies.hashbrown] -version = "0.15" +version = "0.16" features = [ "default-hasher", "inline-more", @@ -137,7 +137,7 @@ features = [ default-features = false [dependencies.indexmap] -version = "2.7" +version = "2.8" default-features = false [dependencies.log] @@ -165,7 +165,7 @@ optional = true default-features = false [dependencies.ron] -version = "0.10" +version = "0.11" optional = true [dependencies.rustc-hash] @@ -182,7 +182,7 @@ optional = true default-features = false [dependencies.smallvec] -version = "1.13.1" +version = "1.14" [dependencies.thiserror] version = "2.0.12" diff --git a/third_party/rust/wgpu-core/src/command/clear.rs b/third_party/rust/wgpu-core/src/command/clear.rs @@ -5,7 +5,7 @@ use core::ops::Range; use crate::command::Command as TraceCommand; use crate::{ api_log, - command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, + command::{encoder::EncodingState, ArcCommand, EncoderStateError}, device::{DeviceError, MissingFeatures}, get_lowest_common_denom, global::Global, @@ -13,7 +13,7 @@ use crate::{ id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{ - DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError, + Buffer, DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError, ParentDevice, RawResourceAccess, ResourceErrorIdent, Texture, TextureClearMode, }, snatch::SnatchGuard, @@ -118,8 +118,18 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - clear_buffer(cmd_buf_data, hub, &cmd_enc, dst, offset, size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ClearBuffer { dst, offset, size }); + } + + cmd_buf_data.push_with(|| -> Result<_, ClearError> { + Ok(ArcCommand::ClearBuffer { + dst: self.resolve_buffer_id(dst)?, + offset, + size, + }) }) } @@ -136,38 +146,38 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - clear_texture_cmd(cmd_buf_data, hub, &cmd_enc, dst, subresource_range) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ClearTexture { + dst, + subresource_range: *subresource_range, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, ClearError> { + Ok(ArcCommand::ClearTexture { + dst: self.resolve_texture_id(dst)?, + subresource_range: *subresource_range, + }) }) } } pub(super) fn clear_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<CommandEncoder>, - dst: BufferId, + state: &mut EncodingState, + dst_buffer: Arc<Buffer>, offset: BufferAddress, size: Option<BufferAddress>, ) -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearBuffer { dst, offset, size }); - } - - cmd_enc.device.check_is_valid()?; - - let dst_buffer = hub.buffers.get(dst).get()?; + dst_buffer.same_device(state.device)?; - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer.check_usage(BufferUsages::COPY_DST)?; // Check if offset & size are valid. @@ -200,20 +210,19 @@ pub(super) fn clear_buffer( } // Mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( &dst_buffer, offset..end_offset, MemoryInitKind::ImplicitlyInitialized, - ), - ); + )); // actual hal barrier & operation - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, state.snatch_guard)); unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.clear_buffer(dst_raw, offset..end_offset); } Ok(()) @@ -227,30 +236,15 @@ pub(super) fn clear_buffer( /// this function, is a lower-level function that encodes a texture clear /// operation without validating it. pub(super) fn clear_texture_cmd( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<CommandEncoder>, - dst: TextureId, + state: &mut EncodingState, + dst_texture: Arc<Texture>, subresource_range: &ImageSubresourceRange, ) -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearTexture { - dst, - subresource_range: *subresource_range, - }); - } - - cmd_enc.device.check_is_valid()?; - - cmd_enc + dst_texture.same_device(state.device)?; + state .device .require_features(wgt::Features::CLEAR_TEXTURE)?; - let dst_texture = hub.textures.get(dst).get()?; - - dst_texture.same_device_as(cmd_enc.as_ref())?; - // Check if subresource aspects are valid. let clear_aspects = hal::FormatAspects::new(dst_texture.desc.format, subresource_range.aspect); if clear_aspects.is_empty() { @@ -283,23 +277,18 @@ pub(super) fn clear_texture_cmd( }); } - let device = &cmd_enc.device; - device.check_is_valid()?; - let (encoder, tracker) = cmd_buf_data.open_encoder_and_tracker()?; - - let snatch_guard = device.snatchable_lock.read(); clear_texture( &dst_texture, TextureInitRange { mip_range: subresource_mip_range, layer_range: subresource_layer_range, }, - encoder, - &mut tracker.textures, - &device.alignments, - device.zero_buffer.as_ref(), - &snatch_guard, - device.instance_flags, + state.raw_encoder, + &mut state.tracker.textures, + &state.device.alignments, + state.device.zero_buffer.as_ref(), + state.snatch_guard, + state.device.instance_flags, )?; Ok(()) diff --git a/third_party/rust/wgpu-core/src/command/compute.rs b/third_party/rust/wgpu-core/src/command/compute.rs @@ -5,13 +5,8 @@ use wgt::{ }; use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; -use core::{fmt, str}; +use core::{convert::Infallible, fmt, str}; -use crate::command::{ - encoder::EncodingState, pass, CommandBufferMutable, CommandEncoder, DebugGroupError, - EncoderStateError, PassStateError, TimestampWritesError, -}; -use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; use crate::{ binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError}, @@ -35,6 +30,14 @@ use crate::{ track::{ResourceUsageCompatibilityError, Tracker, TrackerIndex}, Label, }; +use crate::{command::InnerCommandEncoder, resource::DestroyedResourceError}; +use crate::{ + command::{ + encoder::EncodingState, pass, ArcCommand, CommandEncoder, DebugGroupError, + EncoderStateError, PassStateError, TimestampWritesError, + }, + device::Device, +}; pub type ComputeBasePass = BasePass<ArcComputeCommand, ComputePassError>; @@ -254,10 +257,10 @@ impl WebGpuError for ComputePassError { } } -struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { +struct State<'scope, 'snatch_guard, 'cmd_enc> { pipeline: Option<Arc<ComputePipeline>>, - pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc>, active_query: Option<(Arc<resource::QuerySet>, u32)>, @@ -266,9 +269,7 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { intermediate_trackers: Tracker, } -impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> - State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> -{ +impl<'scope, 'snatch_guard, 'cmd_enc> State<'scope, 'snatch_guard, 'cmd_enc> { fn is_ready(&self) -> Result<(), DispatchError> { if let Some(pipeline) = self.pipeline.as_ref() { self.pass.binder.check_compatibility(pipeline.as_ref())?; @@ -428,7 +429,7 @@ impl Global { pub fn compute_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, - base: BasePass<super::ComputeCommand, core::convert::Infallible>, + base: BasePass<super::ComputeCommand, Infallible>, timestamp_writes: Option<&PassTimestampWrites>, ) { #[cfg(feature = "trace")] @@ -494,57 +495,58 @@ impl Global { let cmd_enc = pass.parent.take().ok_or(EncoderStateError::Ended)?; let mut cmd_buf_data = cmd_enc.data.lock(); - if let Some(err) = pass.base.error.take() { - if matches!( - err, - ComputePassError { - inner: ComputePassErrorInner::EncoderState(EncoderStateError::Ended), - scope: _, - } - ) { - // If the encoder was already finished at time of pass creation, - // then it was not put in the locked state, so we need to - // generate a validation error here due to the encoder not being - // locked. The encoder already has a copy of the error. - return Err(EncoderStateError::Ended); - } else { - // If the pass is invalid, invalidate the parent encoder and return. - // Since we do not track the state of an invalid encoder, it is not - // necessary to unlock it. - cmd_buf_data.invalidate(err); - return Ok(()); - } + cmd_buf_data.unlock_encoder()?; + + let base = pass.base.take(); + + if matches!( + base, + Err(ComputePassError { + inner: ComputePassErrorInner::EncoderState(EncoderStateError::Ended), + scope: _, + }) + ) { + // If the encoder was already finished at time of pass creation, + // then it was not put in the locked state, so we need to + // generate a validation error here and now due to the encoder not + // being locked. The encoder already holds an error from when the + // pass was opened, or earlier. + // + // All other errors are propagated to the encoder within `push_with`, + // and will be reported later. + return Err(EncoderStateError::Ended); } - cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), ComputePassError> { - encode_compute_pass(cmd_buf_data, &cmd_enc, pass) + cmd_buf_data.push_with(|| -> Result<_, ComputePassError> { + Ok(ArcCommand::RunComputePass { + pass: base?, + timestamp_writes: pass.timestamp_writes.take(), + }) }) } } -fn encode_compute_pass( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc<CommandEncoder>, - pass: &mut ComputePass, +pub(super) fn encode_compute_pass( + parent_state: &mut EncodingState<InnerCommandEncoder>, + mut base: BasePass<ArcComputeCommand, Infallible>, + mut timestamp_writes: Option<ArcPassTimestampWrites>, ) -> Result<(), ComputePassError> { let pass_scope = PassErrorScope::Pass; - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; - - let base = &mut pass.base; - - let encoder = &mut cmd_buf_data.encoder; + let device = parent_state.device; // We automatically keep extending command buffers over time, and because // we want to insert a command buffer _before_ what we're about to record, // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - let raw_encoder = encoder + parent_state + .raw_encoder + .close_if_open() + .map_pass_err(pass_scope)?; + let raw_encoder = parent_state + .raw_encoder .open_pass(base.label.as_deref()) .map_pass_err(pass_scope)?; - let snatch_guard = device.snatchable_lock.read(); let mut debug_scope_depth = 0; let mut state = State { @@ -554,23 +556,20 @@ fn encode_compute_pass( base: EncodingState { device, raw_encoder, - tracker: &mut cmd_buf_data.trackers, - buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, - texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data - .indirect_draw_validation_resources, - snatch_guard: &snatch_guard, + tracker: parent_state.tracker, + buffer_memory_init_actions: parent_state.buffer_memory_init_actions, + texture_memory_actions: parent_state.texture_memory_actions, + as_actions: parent_state.as_actions, + temp_resources: parent_state.temp_resources, + indirect_draw_validation_resources: parent_state.indirect_draw_validation_resources, + snatch_guard: parent_state.snatch_guard, debug_scope_depth: &mut debug_scope_depth, }, binder: Binder::new(), temp_offsets: Vec::new(), dynamic_offset_count: 0, - pending_discard_init_fixups: SurfacesInDiscardState::new(), - scope: device.new_usage_scope(), - string_offset: 0, }, active_query: None, @@ -580,7 +579,7 @@ fn encode_compute_pass( intermediate_trackers: Tracker::new(), }; - let indices = &state.pass.base.device.tracker_indices; + let indices = &device.tracker_indices; state .pass .base @@ -595,10 +594,8 @@ fn encode_compute_pass( .set_size(indices.textures.size()); let timestamp_writes: Option<hal::PassTimestampWrites<'_, dyn hal::DynQuerySet>> = - if let Some(tw) = pass.timestamp_writes.take() { - tw.query_set - .same_device_as(cmd_enc.as_ref()) - .map_pass_err(pass_scope)?; + if let Some(tw) = timestamp_writes.take() { + tw.query_set.same_device(device).map_pass_err(pass_scope)?; let query_set = state .pass @@ -658,7 +655,7 @@ fn encode_compute_pass( let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::<ComputePassErrorInner>( &mut state.pass, - cmd_enc.as_ref(), + device, &base.dynamic_offsets, index, num_dynamic_offsets, @@ -669,7 +666,7 @@ fn encode_compute_pass( } ArcComputeCommand::SetPipeline(pipeline) => { let scope = PassErrorScope::SetPipelineCompute; - set_pipeline(&mut state, cmd_enc.as_ref(), pipeline).map_pass_err(scope)?; + set_pipeline(&mut state, device, pipeline).map_pass_err(scope)?; } ArcComputeCommand::SetPushConstant { offset, @@ -699,8 +696,7 @@ fn encode_compute_pass( } ArcComputeCommand::DispatchIndirect { buffer, offset } => { let scope = PassErrorScope::Dispatch { indirect: true }; - dispatch_indirect(&mut state, cmd_enc.as_ref(), buffer, offset) - .map_pass_err(scope)?; + dispatch_indirect(&mut state, device, buffer, offset).map_pass_err(scope)?; } ArcComputeCommand::PushDebugGroup { color: _, len } => { pass::push_debug_group(&mut state.pass, &base.string_data, len); @@ -720,8 +716,8 @@ fn encode_compute_pass( let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::<ComputePassErrorInner>( &mut state.pass, - cmd_enc.as_ref(), - None, + device, + None, // compute passes do not attempt to coalesce query resets query_set, query_index, ) @@ -736,7 +732,7 @@ fn encode_compute_pass( query_set, state.pass.base.raw_encoder, &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), + device, query_index, None, &mut state.active_query, @@ -763,23 +759,22 @@ fn encode_compute_pass( } let State { - pass: - pass::PassState { - base: EncodingState { tracker, .. }, - pending_discard_init_fixups, - .. - }, + pass: pass::PassState { + pending_discard_init_fixups, + .. + }, intermediate_trackers, .. } = state; // Stop the current command encoder. - encoder.close().map_pass_err(pass_scope)?; + parent_state.raw_encoder.close().map_pass_err(pass_scope)?; // Create a new command encoder, which we will insert _before_ the body of the compute pass. // // Use that buffer to insert barriers and clear discarded images. - let transit = encoder + let transit = parent_state + .raw_encoder .open_pass(hal_label( Some("(wgpu internal) Pre Pass"), device.instance_flags, @@ -788,28 +783,31 @@ fn encode_compute_pass( fixup_discarded_surfaces( pending_discard_init_fixups.into_iter(), transit, - &mut tracker.textures, + &mut parent_state.tracker.textures, device, - &snatch_guard, + parent_state.snatch_guard, ); CommandEncoder::insert_barriers_from_tracker( transit, - tracker, + parent_state.tracker, &intermediate_trackers, - &snatch_guard, + parent_state.snatch_guard, ); // Close the command encoder, and swap it with the previous. - encoder.close_and_swap().map_pass_err(pass_scope)?; + parent_state + .raw_encoder + .close_and_swap() + .map_pass_err(pass_scope)?; Ok(()) } fn set_pipeline( state: &mut State, - cmd_enc: &CommandEncoder, + device: &Arc<Device>, pipeline: Arc<ComputePipeline>, ) -> Result<(), ComputePassErrorInner> { - pipeline.same_device_as(cmd_enc)?; + pipeline.same_device(device)?; state.pipeline = Some(pipeline.clone()); @@ -886,11 +884,11 @@ fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorI fn dispatch_indirect( state: &mut State, - cmd_enc: &CommandEncoder, + device: &Arc<Device>, buffer: Arc<Buffer>, offset: u64, ) -> Result<(), ComputePassErrorInner> { - buffer.same_device_as(cmd_enc)?; + buffer.same_device(device)?; state.is_ready()?; diff --git a/third_party/rust/wgpu-core/src/command/encoder.rs b/third_party/rust/wgpu-core/src/command/encoder.rs @@ -1,22 +1,45 @@ use alloc::{sync::Arc, vec::Vec}; use crate::{ - command::memory_init::CommandBufferTextureMemoryActions, device::Device, - init_tracker::BufferInitTrackerAction, ray_tracing::AsAction, snatch::SnatchGuard, + command::memory_init::CommandBufferTextureMemoryActions, + device::{queue::TempResource, Device}, + init_tracker::BufferInitTrackerAction, + ray_tracing::AsAction, + snatch::SnatchGuard, track::Tracker, }; -/// State applicable when encoding commands onto a compute pass, or onto a -/// render pass, or directly with a command encoder. -pub(crate) struct EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder> { +/// State applicable when encoding commands onto a compute pass, render pass, or +/// directly to a command encoder. +/// +/// Most encoding routines just want to receive an open encoder, write +/// command(s) to it, and leave it open for whatever is next. In this case the +/// `E` type parameter has the default value of `dyn hal::DynCommandEncoder`. To +/// avoid confusion about encoder state, we set the convention that _the encoder +/// in an `EncodingState` holding a bare HAL reference must always be open_. +/// +/// Compute and render passes are more complicated. Because they record a +/// command buffer for a housekeeping pre-pass which is inserted before the pass +/// itself, the first thing they will do is close and reopen the encoder if it +/// is already open. Unnecessary empty HAL passes can be avoided by passing them +/// the encoder in whatever state it happens to be. In this case, `E` is +/// `InnerCommandEncoder`, which tracks the state of the encoder. The callee +/// (the render or compute pass) will open and close the encoder as necessary. +/// +/// This structure is not supported by cbindgen because it contains a trait +/// object reference. +/// +/// cbindgen:ignore +pub(crate) struct EncodingState<'snatch_guard, 'cmd_enc, E: ?Sized = dyn hal::DynCommandEncoder> { pub(crate) device: &'cmd_enc Arc<Device>, - pub(crate) raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, + pub(crate) raw_encoder: &'cmd_enc mut E, pub(crate) tracker: &'cmd_enc mut Tracker, pub(crate) buffer_memory_init_actions: &'cmd_enc mut Vec<BufferInitTrackerAction>, pub(crate) texture_memory_actions: &'cmd_enc mut CommandBufferTextureMemoryActions, pub(crate) as_actions: &'cmd_enc mut Vec<AsAction>, + pub(crate) temp_resources: &'cmd_enc mut Vec<TempResource>, pub(crate) indirect_draw_validation_resources: &'cmd_enc mut crate::indirect_validation::DrawResources, diff --git a/third_party/rust/wgpu-core/src/command/encoder_command.rs b/third_party/rust/wgpu-core/src/command/encoder_command.rs @@ -1,8 +1,11 @@ use core::convert::Infallible; -use alloc::{string::String, vec::Vec}; +use alloc::{string::String, sync::Arc, vec::Vec}; -use crate::id; +use crate::{ + id, + resource::{Buffer, QuerySet, Texture}, +}; #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -68,3 +71,71 @@ pub enum Command { tlas: Vec<crate::ray_tracing::TraceTlasPackage>, }, } + +#[derive(Clone, Debug)] +pub enum ArcCommand { + CopyBufferToBuffer { + src: Arc<Buffer>, + src_offset: wgt::BufferAddress, + dst: Arc<Buffer>, + dst_offset: wgt::BufferAddress, + size: Option<wgt::BufferAddress>, + }, + CopyBufferToTexture { + src: wgt::TexelCopyBufferInfo<Arc<Buffer>>, + dst: wgt::TexelCopyTextureInfo<Arc<Texture>>, + size: wgt::Extent3d, + }, + CopyTextureToBuffer { + src: wgt::TexelCopyTextureInfo<Arc<Texture>>, + dst: wgt::TexelCopyBufferInfo<Arc<Buffer>>, + size: wgt::Extent3d, + }, + CopyTextureToTexture { + src: wgt::TexelCopyTextureInfo<Arc<Texture>>, + dst: wgt::TexelCopyTextureInfo<Arc<Texture>>, + size: wgt::Extent3d, + }, + ClearBuffer { + dst: Arc<Buffer>, + offset: wgt::BufferAddress, + size: Option<wgt::BufferAddress>, + }, + ClearTexture { + dst: Arc<Texture>, + subresource_range: wgt::ImageSubresourceRange, + }, + WriteTimestamp { + query_set: Arc<QuerySet>, + query_index: u32, + }, + ResolveQuerySet { + query_set: Arc<QuerySet>, + start_query: u32, + query_count: u32, + destination: Arc<Buffer>, + destination_offset: wgt::BufferAddress, + }, + PushDebugGroup(String), + PopDebugGroup, + InsertDebugMarker(String), + RunComputePass { + pass: super::BasePass<super::ArcComputeCommand, Infallible>, + timestamp_writes: Option<super::ArcPassTimestampWrites>, + }, + RunRenderPass { + pass: super::BasePass<super::ArcRenderCommand, Infallible>, + color_attachments: super::ArcRenderPassColorAttachmentArray, + depth_stencil_attachment: Option<super::ArcRenderPassDepthStencilAttachment>, + timestamp_writes: Option<super::ArcPassTimestampWrites>, + occlusion_query_set: Option<Arc<QuerySet>>, + }, + BuildAccelerationStructures { + blas: Vec<crate::ray_tracing::ArcBlasBuildEntry>, + tlas: Vec<crate::ray_tracing::ArcTlasPackage>, + }, + TransitionResources { + buffer_transitions: Vec<wgt::BufferTransition<Arc<Buffer>>>, + texture_transitions: Vec<wgt::TextureTransition<Arc<Texture>>>, + }, +} diff --git a/third_party/rust/wgpu-core/src/command/mod.rs b/third_party/rust/wgpu-core/src/command/mod.rs @@ -1,3 +1,13 @@ +//! # Command Encoding +//! +//! TODO: High-level description of command encoding. +//! +//! The convention in this module is that functions accepting a [`&mut dyn +//! hal::DynCommandEncoder`] are low-level helpers and may assume the encoder is +//! in the open state, ready to encode commands. Encoders that are not open +//! should be nested within some other container that provides additional +//! state tracking, like [`InnerCommandEncoder`]. + mod allocator; mod bind; mod bundle; @@ -19,22 +29,37 @@ mod transfer; mod transition_resources; use alloc::{borrow::ToOwned as _, boxed::Box, string::String, sync::Arc, vec::Vec}; +use core::convert::Infallible; use core::mem::{self, ManuallyDrop}; use core::ops; pub(crate) use self::clear::clear_texture; pub use self::{ - bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, - encoder_command::Command, query::*, render::*, render_command::RenderCommand, transfer::*, + bundle::*, + clear::ClearError, + compute::*, + compute_command::{ArcComputeCommand, ComputeCommand}, + draw::*, + encoder_command::{ArcCommand, Command}, + query::*, + render::*, + render_command::{ArcRenderCommand, RenderCommand}, + transfer::*, }; pub(crate) use allocator::CommandAllocator; pub(crate) use timestamp_writes::ArcPassTimestampWrites; pub use timestamp_writes::PassTimestampWrites; -use self::memory_init::CommandBufferTextureMemoryActions; +use self::{ + clear::{clear_buffer, clear_texture_cmd}, + memory_init::CommandBufferTextureMemoryActions, + ray_tracing::build_acceleration_structures, + transition_resources::transition_resources, +}; use crate::binding_model::BindingError; +use crate::command::encoder::EncodingState; use crate::command::transition_resources::TransitionResourcesError; use crate::device::queue::TempResource; use crate::device::{Device, DeviceError, MissingFeatures}; @@ -123,12 +148,21 @@ pub(crate) enum CommandEncoderStatus { } impl CommandEncoderStatus { - /// Record commands using the supplied closure. + #[cfg(feature = "trace")] + fn trace(&mut self) -> Option<&mut Vec<TraceCommand>> { + match self { + Self::Recording(cmd_buf_data) => cmd_buf_data.trace_commands.as_mut(), + _ => None, + } + } + + /// Push a command provided by a closure onto the encoder. /// /// If the encoder is in the [`Self::Recording`] state, calls the closure to - /// record commands. If the closure returns an error, stores that error in - /// the encoder for later reporting when `finish()` is called. Returns - /// `Ok(())` even if the closure returned an error. + /// obtain a command, and pushes it onto the encoder. If the closure returns + /// an error, stores that error in the encoder for later reporting when + /// `finish()` is called. Returns `Ok(())` even if the closure returned an + /// error. /// /// If the encoder is not in the [`Self::Recording`] state, the closure will /// not be called and nothing will be recorded. The encoder will be @@ -137,7 +171,51 @@ impl CommandEncoderStatus { /// returns `Ok(())`. /// /// [ves]: https://www.w3.org/TR/webgpu/#abstract-opdef-validate-the-encoder-state - fn record_with< + fn push_with<F: FnOnce() -> Result<ArcCommand, E>, E: Clone + Into<CommandEncoderError>>( + &mut self, + f: F, + ) -> Result<(), EncoderStateError> { + match self { + Self::Recording(cmd_buf_data) => { + match f() { + Ok(cmd) => cmd_buf_data.commands.push(cmd), + Err(err) => { + self.invalidate(err); + } + } + Ok(()) + } + Self::Locked(_) => { + // Invalidate the encoder and do not record anything, but do not + // return an immediate validation error. + self.invalidate(EncoderStateError::Locked); + Ok(()) + } + // Encoder is ended. Invalidate the encoder, do not record anything, + // and return an immediate validation error. + Self::Finished(_) => Err(self.invalidate(EncoderStateError::Ended)), + Self::Consumed => Err(EncoderStateError::Ended), + // Encoder is already invalid. Do not record anything, but do not + // return an immediate validation error. + Self::Error(_) => Ok(()), + Self::Transitioning => unreachable!(), + } + } + + /// Call a closure with the inner command buffer structure. + /// + /// If the encoder is in the [`Self::Recording`] state, calls the provided + /// closure. If the closure returns an error, stores that error in the + /// encoder for later reporting when `finish()` is called. Returns `Ok(())` + /// even if the closure returned an error. + /// + /// If the encoder is not in the [`Self::Recording`] state, the closure will + /// not be called. The encoder will be invalidated (if it is not already). + /// If the error is a [validation error that should be raised + /// immediately][ves], returns it in `Err`, otherwise, returns `Ok(())`. + /// + /// [ves]: https://www.w3.org/TR/webgpu/#abstract-opdef-validate-the-encoder-state + fn with_buffer< F: FnOnce(&mut CommandBufferMutable) -> Result<(), E>, E: Clone + Into<CommandEncoderError>, >( @@ -193,7 +271,7 @@ impl CommandEncoderStatus { } } - #[cfg(feature = "trace")] + #[cfg(all(feature = "trace", any(feature = "serde", feature = "replay")))] fn get_inner(&mut self) -> &mut CommandBufferMutable { match self { Self::Locked(inner) | Self::Finished(inner) | Self::Recording(inner) => inner, @@ -210,7 +288,7 @@ impl CommandEncoderStatus { /// Locks the encoder by putting it in the [`Self::Locked`] state. /// /// Render or compute passes call this on start. At the end of the pass, - /// they call [`Self::unlock_and_record`] to put the [`CommandBuffer`] back + /// they call [`Self::unlock_encoder`] to put the [`CommandBuffer`] back /// into the [`Self::Recording`] state. fn lock_encoder(&mut self) -> Result<(), EncoderStateError> { match mem::replace(self, Self::Transitioning) { @@ -238,32 +316,19 @@ impl CommandEncoderStatus { } } - /// Unlocks the [`CommandBuffer`] and puts it back into the - /// [`Self::Recording`] state, then records commands using the supplied - /// closure. + /// Unlocks the encoder and puts it back into the [`Self::Recording`] state. /// /// This function is the unlocking counterpart to [`Self::lock_encoder`]. It /// is only valid to call this function if the encoder is in the /// [`Self::Locked`] state. /// - /// If the closure returns an error, stores that error in the encoder for - /// later reporting when `finish()` is called. Returns `Ok(())` even if the - /// closure returned an error. - /// - /// If the encoder is not in the [`Self::Locked`] state, the closure will - /// not be called and nothing will be recorded. If a validation error should - /// be raised immediately, returns it in `Err`, otherwise, returns `Ok(())`. - fn unlock_and_record< - F: FnOnce(&mut CommandBufferMutable) -> Result<(), E>, - E: Clone + Into<CommandEncoderError>, - >( - &mut self, - f: F, - ) -> Result<(), EncoderStateError> { + /// If the encoder is in a state other than [`Self::Locked`] and a + /// validation error should be raised immediately, returns it in `Err`, + /// otherwise, stores the error in the encoder and returns `Ok(())`. + fn unlock_encoder(&mut self) -> Result<(), EncoderStateError> { match mem::replace(self, Self::Transitioning) { Self::Locked(inner) => { *self = Self::Recording(inner); - RecordingGuard { inner: self }.record(f); Ok(()) } st @ Self::Finished(_) => { @@ -279,8 +344,8 @@ impl CommandEncoderStatus { Err(EncoderStateError::Ended) } st @ Self::Error(_) => { - // Encoder is invalid. Do not record anything, but do not - // return an immediate validation error. + // Encoder is already invalid. The error will be reported by + // `CommandEncoder.finish`. *self = st; Ok(()) } @@ -292,18 +357,10 @@ impl CommandEncoderStatus { // Replace our state with `Consumed`, and return either the inner // state or an error, to be transferred to the command buffer. match mem::replace(self, Self::Consumed) { - Self::Recording(mut inner) => { - if let Err(err) = inner.encoder.close_if_open() { - Self::Error(err.into()) - } else if inner.debug_scope_depth > 0 { - Self::Error(CommandEncoderError::DebugGroupError( - DebugGroupError::MissingPop, - )) - } else { - // Note: if we want to stop tracking the swapchain texture view, - // this is the place to do it. - Self::Finished(inner) - } + Self::Recording(inner) => { + // Nothing should have opened the encoder yet. + assert!(!inner.encoder.is_open); + Self::Finished(inner) } Self::Consumed | Self::Finished(_) => Self::Error(EncoderStateError::Ended.into()), Self::Locked(_) => Self::Error(EncoderStateError::Locked.into()), @@ -574,6 +631,22 @@ impl InnerCommandEncoder { Ok(()) } + /// If the command encoder is not open, begin recording a new command buffer. + /// + /// If the command encoder was already open, does nothing. + /// + /// In both cases, returns a reference to the raw encoder. + fn open_if_closed(&mut self) -> Result<&mut dyn hal::DynCommandEncoder, DeviceError> { + if !self.is_open { + self.is_open = true; + let hal_label = hal_label(Some(self.label.as_str()), self.device.instance_flags); + unsafe { self.raw.begin_encoding(hal_label) } + .map_err(|e| self.device.handle_hal_error(e))?; + } + + Ok(self.raw.as_mut()) + } + /// Begin recording a new command buffer, if we haven't already. /// /// The underlying hal encoder is put in the "recording" state. @@ -588,7 +661,7 @@ impl InnerCommandEncoder { Ok(self.raw.as_mut()) } - /// Begin recording a new command buffer for a render pass, with + /// Begin recording a new command buffer for a render or compute pass, with /// its own label. /// /// The underlying hal encoder is put in the "recording" state. @@ -661,22 +734,13 @@ pub struct CommandBufferMutable { indirect_draw_validation_resources: crate::indirect_validation::DrawResources, - debug_scope_depth: u32, + pub(crate) commands: Vec<ArcCommand>, #[cfg(feature = "trace")] pub(crate) trace_commands: Option<Vec<TraceCommand>>, } impl CommandBufferMutable { - pub(crate) fn open_encoder_and_tracker( - &mut self, - ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { - let encoder = self.encoder.open()?; - let tracker = &mut self.trackers; - - Ok((encoder, tracker)) - } - pub(crate) fn into_baked_commands(self) -> BakedCommands { BakedCommands { encoder: self.encoder, @@ -735,7 +799,7 @@ impl CommandEncoder { temp_resources: Default::default(), indirect_draw_validation_resources: crate::indirect_validation::DrawResources::new(device.clone()), - debug_scope_depth: 0, + commands: Vec::new(), #[cfg(feature = "trace")] trace_commands: if device.trace.lock().is_some() { Some(Vec::new()) @@ -883,6 +947,10 @@ pub struct BasePass<C, E> { pub error: Option<E>, /// The stream of commands. + /// + /// The commands are moved out of this vector when the pass is ended (i.e. + /// at the same time that `parent` is taken out of the + /// `ComputePass`/`RenderPass`). pub commands: Vec<C>, /// Dynamic offsets consumed by [`SetBindGroup`] commands in `commands`. @@ -926,6 +994,26 @@ impl<C: Clone, E: Clone> BasePass<C, E> { push_constant_data: Vec::new(), } } + + /// Takes the commands from the pass, or returns an error if the pass is + /// invalid. + /// + /// This is called when the pass is ended, at the same time that the + /// `parent` member of the `ComputePass` or `RenderPass` containing the pass + /// is taken. + fn take(&mut self) -> Result<BasePass<C, Infallible>, E> { + match self.error.as_ref() { + Some(err) => Err(err.clone()), + None => Ok(BasePass { + label: self.label.clone(), + error: None, + commands: mem::take(&mut self.commands), + dynamic_offsets: mem::take(&mut self.dynamic_offsets), + string_data: mem::take(&mut self.string_data), + push_constant_data: mem::take(&mut self.push_constant_data), + }), + } + } } /// Checks the state of a [`compute::ComputePass`] or [`render::RenderPass`] and @@ -1169,20 +1257,21 @@ impl Global { &self, buffer_id: Id<id::markers::Buffer>, ) -> Result<Arc<crate::resource::Buffer>, InvalidResourceError> { - let hub = &self.hub; - let buffer = hub.buffers.get(buffer_id).get()?; + self.hub.buffers.get(buffer_id).get() + } - Ok(buffer) + fn resolve_texture_id( + &self, + texture_id: Id<id::markers::Texture>, + ) -> Result<Arc<crate::resource::Texture>, InvalidResourceError> { + self.hub.textures.get(texture_id).get() } fn resolve_query_set( &self, query_set_id: Id<id::markers::QuerySet>, ) -> Result<Arc<QuerySet>, InvalidResourceError> { - let hub = &self.hub; - let query_set = hub.query_sets.get(query_set_id).get()?; - - Ok(query_set) + self.hub.query_sets.get(query_set_id).get() } pub fn command_encoder_finish( @@ -1196,14 +1285,196 @@ impl Global { let hub = &self.hub; let cmd_enc = hub.command_encoders.get(encoder_id); + let mut cmd_enc_status = cmd_enc.data.lock(); - let data = cmd_enc.data.lock().finish(); + let res = match cmd_enc_status.finish() { + CommandEncoderStatus::Finished(cmd_buf_data) => Ok(cmd_buf_data), + CommandEncoderStatus::Error(err) => Err(err), + _ => unreachable!(), + }; - // Errors related to destroyed resources are not reported until the - // command buffer is submitted. - let error = match data { - CommandEncoderStatus::Error(ref e) if !e.is_destroyed_error() => Some(e.clone()), - _ => None, + let res = res.and_then(|mut cmd_buf_data| { + cmd_enc.device.check_is_valid()?; + let snatch_guard = cmd_enc.device.snatchable_lock.read(); + let mut debug_scope_depth = 0; + + let mut commands = mem::take(&mut cmd_buf_data.commands); + for command in commands.drain(..) { + if matches!( + command, + ArcCommand::RunRenderPass { .. } | ArcCommand::RunComputePass { .. } + ) { + // Compute passes and render passes can accept either an + // open or closed encoder. This state object holds an + // `InnerCommandEncoder`. See the documentation of + // [`EncodingState`]. + let mut state = EncodingState { + device: &cmd_enc.device, + raw_encoder: &mut cmd_buf_data.encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + temp_resources: &mut cmd_buf_data.temp_resources, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }; + + match command { + ArcCommand::RunRenderPass { + pass, + color_attachments, + depth_stencil_attachment, + timestamp_writes, + occlusion_query_set, + } => { + encode_render_pass( + &mut state, + pass, + color_attachments, + depth_stencil_attachment, + timestamp_writes, + occlusion_query_set, + )?; + } + ArcCommand::RunComputePass { + pass, + timestamp_writes, + } => { + encode_compute_pass(&mut state, pass, timestamp_writes)?; + } + _ => unreachable!(), + } + } else { + // All the other non-pass encoding routines assume the + // encoder is open, so open it if necessary. This state + // object holds an `&mut dyn hal::DynCommandEncoder`. By + // convention, a bare HAL encoder reference in + // [`EncodingState`] must always be an open encoder. + let raw_encoder = cmd_buf_data.encoder.open_if_closed()?; + let mut state = EncodingState { + device: &cmd_enc.device, + raw_encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + temp_resources: &mut cmd_buf_data.temp_resources, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }; + match command { + ArcCommand::CopyBufferToBuffer { + src, + src_offset, + dst, + dst_offset, + size, + } => { + copy_buffer_to_buffer( + &mut state, &src, src_offset, &dst, dst_offset, size, + )?; + } + ArcCommand::CopyBufferToTexture { src, dst, size } => { + copy_buffer_to_texture(&mut state, &src, &dst, &size)?; + } + ArcCommand::CopyTextureToBuffer { src, dst, size } => { + copy_texture_to_buffer(&mut state, &src, &dst, &size)?; + } + ArcCommand::CopyTextureToTexture { src, dst, size } => { + copy_texture_to_texture(&mut state, &src, &dst, &size)?; + } + ArcCommand::ClearBuffer { dst, offset, size } => { + clear_buffer(&mut state, dst, offset, size)?; + } + ArcCommand::ClearTexture { + dst, + subresource_range, + } => { + clear_texture_cmd(&mut state, dst, &subresource_range)?; + } + ArcCommand::WriteTimestamp { + query_set, + query_index, + } => { + write_timestamp(&mut state, query_set, query_index)?; + } + ArcCommand::ResolveQuerySet { + query_set, + start_query, + query_count, + destination, + destination_offset, + } => { + resolve_query_set( + &mut state, + query_set, + start_query, + query_count, + destination, + destination_offset, + )?; + } + ArcCommand::PushDebugGroup(label) => { + push_debug_group(&mut state, &label)?; + } + ArcCommand::PopDebugGroup => { + pop_debug_group(&mut state)?; + } + ArcCommand::InsertDebugMarker(label) => { + insert_debug_marker(&mut state, &label)?; + } + ArcCommand::BuildAccelerationStructures { blas, tlas } => { + build_acceleration_structures(&mut state, blas, tlas)?; + } + ArcCommand::TransitionResources { + buffer_transitions, + texture_transitions, + } => { + transition_resources( + &mut state, + buffer_transitions, + texture_transitions, + )?; + } + ArcCommand::RunComputePass { .. } | ArcCommand::RunRenderPass { .. } => { + unreachable!() + } + } + } + } + + if debug_scope_depth > 0 { + Err(CommandEncoderError::DebugGroupError( + DebugGroupError::MissingPop, + ))?; + } + + // Close the encoder, unless it was closed already by a render or compute pass. + cmd_buf_data.encoder.close_if_open()?; + + // Note: if we want to stop tracking the swapchain texture view, + // this is the place to do it. + + Ok(cmd_buf_data) + }); + + let (data, error) = match res { + Err(e) => { + if e.is_destroyed_error() { + // Errors related to destroyed resources are not reported until the + // command buffer is submitted. + (CommandEncoderStatus::Error(e.clone()), None) + } else { + (CommandEncoderStatus::Error(e.clone()), Some(e)) + } + } + + Ok(data) => (CommandEncoderStatus::Finished(data), None), }; let cmd_buf = CommandBuffer { @@ -1229,8 +1500,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - push_debug_group(cmd_buf_data, &cmd_enc, label) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::PushDebugGroup(label.to_owned())); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::PushDebugGroup(label.to_owned())) }) } @@ -1246,8 +1523,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - insert_debug_marker(cmd_buf_data, &cmd_enc, label) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::InsertDebugMarker(label.to_owned())); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::InsertDebugMarker(label.to_owned())) }) } @@ -1262,9 +1545,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - pop_debug_group(cmd_buf_data, &cmd_enc) - }) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::PopDebugGroup); + } + + cmd_buf_data + .push_with(|| -> Result<_, CommandEncoderError> { Ok(ArcCommand::PopDebugGroup) }) } fn validate_pass_timestamp_writes<E>( @@ -1320,84 +1608,49 @@ impl Global { } pub(crate) fn push_debug_group( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc<CommandEncoder>, + state: &mut EncodingState, label: &str, ) -> Result<(), CommandEncoderError> { - cmd_buf_data.debug_scope_depth += 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PushDebugGroup(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; + *state.debug_scope_depth += 1; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - unsafe { - cmd_buf_raw.begin_debug_marker(label); - } + unsafe { state.raw_encoder.begin_debug_marker(label) }; } Ok(()) } pub(crate) fn insert_debug_marker( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc<CommandEncoder>, + state: &mut EncodingState, label: &str, ) -> Result<(), CommandEncoderError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::InsertDebugMarker(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; - - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.insert_debug_marker(label); - } + unsafe { state.raw_encoder.insert_debug_marker(label) }; } Ok(()) } -pub(crate) fn pop_debug_group( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc<CommandEncoder>, -) -> Result<(), CommandEncoderError> { - if cmd_buf_data.debug_scope_depth == 0 { +pub(crate) fn pop_debug_group(state: &mut EncodingState) -> Result<(), CommandEncoderError> { + if *state.debug_scope_depth == 0 { return Err(DebugGroupError::InvalidPop.into()); } - cmd_buf_data.debug_scope_depth -= 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PopDebugGroup); - } + *state.debug_scope_depth -= 1; - cmd_enc.device.check_is_valid()?; - - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - unsafe { - cmd_buf_raw.end_debug_marker(); - } + unsafe { state.raw_encoder.end_debug_marker() }; } Ok(()) diff --git a/third_party/rust/wgpu-core/src/command/pass.rs b/third_party/rust/wgpu-core/src/command/pass.rs @@ -4,8 +4,8 @@ use crate::binding_model::{BindError, BindGroup, PushConstantUploadError}; use crate::command::bind::Binder; use crate::command::encoder::EncodingState; use crate::command::memory_init::SurfacesInDiscardState; -use crate::command::{CommandEncoder, DebugGroupError, QueryResetMap, QueryUseError}; -use crate::device::{DeviceError, MissingFeatures}; +use crate::command::{DebugGroupError, QueryResetMap, QueryUseError}; +use crate::device::{Device, DeviceError, MissingFeatures}; use crate::pipeline::LateSizedBufferGroup; use crate::ray_tracing::AsAction; use crate::resource::{DestroyedResourceError, Labeled, ParentDevice, QuerySet}; @@ -41,8 +41,8 @@ impl WebGpuError for InvalidValuesOffset { } } -pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { - pub(crate) base: EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder>, +pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc> { + pub(crate) base: EncodingState<'snatch_guard, 'cmd_enc>, /// Immediate texture inits required because of prior discards. Need to /// be inserted before texture reads. @@ -61,7 +61,7 @@ pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { pub(crate) fn set_bind_group<E>( state: &mut PassState, - cmd_enc: &CommandEncoder, + device: &Arc<Device>, dynamic_offsets: &[DynamicOffset], index: u32, num_dynamic_offsets: usize, @@ -108,7 +108,7 @@ where let bind_group = bind_group.unwrap(); let bind_group = state.base.tracker.bind_groups.insert_single(bind_group); - bind_group.same_device_as(cmd_enc)?; + bind_group.same_device(device)?; bind_group.validate_dynamic_bindings(index, &state.temp_offsets)?; @@ -271,7 +271,7 @@ where pub(crate) fn write_timestamp<E>( state: &mut PassState, - cmd_enc: &CommandEncoder, + device: &Arc<Device>, pending_query_resets: Option<&mut QueryResetMap>, query_set: Arc<QuerySet>, query_index: u32, @@ -284,7 +284,7 @@ where query_set.error_ident() ); - query_set.same_device_as(cmd_enc)?; + query_set.same_device(device)?; state .base diff --git a/third_party/rust/wgpu-core/src/command/query.rs b/third_party/rust/wgpu-core/src/command/query.rs @@ -4,14 +4,14 @@ use core::{iter, mem}; #[cfg(feature = "trace")] use crate::command::Command as TraceCommand; use crate::{ - command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, - device::{DeviceError, MissingFeatures}, + command::{encoder::EncodingState, ArcCommand, EncoderStateError}, + device::{Device, DeviceError, MissingFeatures}, global::Global, id, init_tracker::MemoryInitKind, resource::{ - DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, ParentDevice, - QuerySet, RawResourceAccess, Trackable, + Buffer, DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, + ParentDevice, QuerySet, RawResourceAccess, Trackable, }, track::{StatelessTracker, TrackerIndex}, FastHashMap, @@ -307,12 +307,12 @@ pub(super) fn validate_and_begin_pipeline_statistics_query( query_set: Arc<QuerySet>, raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker<QuerySet>, - cmd_enc: &CommandEncoder, + device: &Arc<Device>, query_index: u32, reset_state: Option<&mut QueryResetMap>, active_query: &mut Option<(Arc<QuerySet>, u32)>, ) -> Result<(), QueryUseError> { - query_set.same_device_as(cmd_enc)?; + query_set.same_device(device)?; let needs_reset = reset_state.is_none(); query_set.validate_query( @@ -365,8 +365,20 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - write_timestamp(cmd_buf_data, hub, &cmd_enc, query_set_id, query_index) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::WriteTimestamp { + query_set_id, + query_index, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, QueryError> { + Ok(ArcCommand::WriteTimestamp { + query_set: self.resolve_query_set(query_set_id)?, + query_index, + }) }) } @@ -383,97 +395,70 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - resolve_query_set( - cmd_buf_data, - hub, - &cmd_enc, + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ResolveQuerySet { query_set_id, start_query, query_count, destination, destination_offset, - ) + }); + } + + cmd_buf_data.push_with(|| -> Result<_, QueryError> { + Ok(ArcCommand::ResolveQuerySet { + query_set: self.resolve_query_set(query_set_id)?, + start_query, + query_count, + destination: self.resolve_buffer_id(destination)?, + destination_offset, + }) }) } } pub(super) fn write_timestamp( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<CommandEncoder>, - query_set_id: id::QuerySetId, + state: &mut EncodingState, + query_set: Arc<QuerySet>, query_index: u32, ) -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::WriteTimestamp { - query_set_id, - query_index, - }); - } - - cmd_enc.device.check_is_valid()?; - - cmd_enc + state .device .require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS)?; - let raw_encoder = cmd_buf_data.encoder.open()?; + query_set.same_device(state.device)?; - let query_set = hub.query_sets.get(query_set_id).get()?; - query_set.same_device_as(cmd_enc.as_ref())?; + query_set.validate_and_write_timestamp(state.raw_encoder, query_index, None)?; - query_set.validate_and_write_timestamp(raw_encoder, query_index, None)?; - - cmd_buf_data.trackers.query_sets.insert_single(query_set); + state.tracker.query_sets.insert_single(query_set); Ok(()) } pub(super) fn resolve_query_set( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<CommandEncoder>, - query_set_id: id::QuerySetId, + state: &mut EncodingState, + query_set: Arc<QuerySet>, start_query: u32, query_count: u32, - destination: id::BufferId, + dst_buffer: Arc<Buffer>, destination_offset: BufferAddress, ) -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ResolveQuerySet { - query_set_id, - start_query, - query_count, - destination, - destination_offset, - }); - } - - cmd_enc.device.check_is_valid()?; - if destination_offset % wgt::QUERY_RESOLVE_BUFFER_ALIGNMENT != 0 { return Err(QueryError::Resolve(ResolveError::BufferOffsetAlignment)); } - let query_set = hub.query_sets.get(query_set_id).get()?; + query_set.same_device(state.device)?; + dst_buffer.same_device(state.device)?; - query_set.same_device_as(cmd_enc.as_ref())?; + dst_buffer.check_destroyed(state.snatch_guard)?; - let dst_buffer = hub.buffers.get(destination).get()?; - - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - dst_buffer.check_destroyed(&snatch_guard)?; - - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, state.snatch_guard)); dst_buffer .check_usage(wgt::BufferUsages::QUERY_RESOLVE) @@ -517,19 +502,18 @@ pub(super) fn resolve_query_set( })?; // TODO(https://github.com/gfx-rs/wgpu/issues/3993): Need to track initialization state. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( &dst_buffer, buffer_start_offset..buffer_end_offset, MemoryInitKind::ImplicitlyInitialized, - ), - ); + )); - let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; - let raw_encoder = cmd_buf_data.encoder.open()?; + let raw_dst_buffer = dst_buffer.try_raw(state.snatch_guard)?; unsafe { - raw_encoder.transition_buffers(dst_barrier.as_slice()); - raw_encoder.copy_query_results( + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.copy_query_results( query_set.raw(), start_query..end_query, raw_dst_buffer, @@ -540,26 +524,21 @@ pub(super) fn resolve_query_set( if matches!(query_set.desc.ty, wgt::QueryType::Timestamp) { // Timestamp normalization is only needed for timestamps. - cmd_enc - .device - .timestamp_normalizer - .get() - .unwrap() - .normalize( - &snatch_guard, - raw_encoder, - &mut cmd_buf_data.trackers.buffers, - dst_buffer - .timestamp_normalization_bind_group - .get(&snatch_guard) - .unwrap(), - &dst_buffer, - destination_offset, - query_count, - ); + state.device.timestamp_normalizer.get().unwrap().normalize( + state.snatch_guard, + state.raw_encoder, + &mut state.tracker.buffers, + dst_buffer + .timestamp_normalization_bind_group + .get(state.snatch_guard) + .unwrap(), + &dst_buffer, + destination_offset, + query_count, + ); } - cmd_buf_data.trackers.query_sets.insert_single(query_set); + state.tracker.query_sets.insert_single(query_set); Ok(()) } diff --git a/third_party/rust/wgpu-core/src/command/ray_tracing.rs b/third_party/rust/wgpu-core/src/command/ray_tracing.rs @@ -1,4 +1,4 @@ -use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use alloc::{sync::Arc, vec::Vec}; use core::{ cmp::max, num::NonZeroU64, @@ -11,34 +11,39 @@ use crate::{ command::CommandBufferMutable, device::queue::TempResource, global::Global, - hub::Hub, id::CommandEncoderId, init_tracker::MemoryInitKind, ray_tracing::{ - BlasBuildEntry, BlasGeometries, BlasTriangleGeometry, BuildAccelerationStructureError, - TlasInstance, TlasPackage, TraceBlasBuildEntry, TraceBlasGeometries, - TraceBlasTriangleGeometry, TraceTlasInstance, TraceTlasPackage, + BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasPackage, + TraceBlasBuildEntry, TraceBlasGeometries, TraceBlasTriangleGeometry, TraceTlasInstance, + TraceTlasPackage, }, resource::{Blas, BlasCompactState, Buffer, Labeled, StagingBuffer, Tlas}, scratch::ScratchBuffer, snatch::SnatchGuard, track::PendingTransition, }; +use crate::{command::EncoderStateError, device::resource::CommandIndices}; use crate::{ - command::CommandEncoder, - ray_tracing::{AsAction, AsBuild, TlasBuild, ValidateAsActionsError}, + command::{encoder::EncodingState, ArcCommand}, + ray_tracing::{ + ArcBlasBuildEntry, ArcBlasGeometries, ArcBlasTriangleGeometry, ArcTlasInstance, + ArcTlasPackage, AsAction, AsBuild, BlasTriangleGeometryInfo, TlasBuild, + ValidateAsActionsError, + }, + resource::InvalidResourceError, + track::Tracker, }; -use crate::{command::EncoderStateError, device::resource::CommandIndices}; use crate::{lock::RwLockWriteGuard, resource::RawResourceAccess}; use crate::id::{BlasId, TlasId}; -struct TriangleBufferStore<'a> { +struct TriangleBufferStore { vertex_buffer: Arc<Buffer>, vertex_transition: Option<PendingTransition<BufferUses>>, index_buffer_transition: Option<(Arc<Buffer>, Option<PendingTransition<BufferUses>>)>, transform_buffer_transition: Option<(Arc<Buffer>, Option<PendingTransition<BufferUses>>)>, - geometry: BlasTriangleGeometry<'a>, + geometry: BlasTriangleGeometryInfo, ending_blas: Option<Arc<Blas>>, } @@ -60,6 +65,14 @@ struct TlasStore<'a> { } impl Global { + fn resolve_blas_id(&self, blas_id: BlasId) -> Result<Arc<Blas>, InvalidResourceError> { + self.hub.blas_s.get(blas_id).get() + } + + fn resolve_tlas_id(&self, tlas_id: TlasId) -> Result<Arc<Tlas>, InvalidResourceError> { + self.hub.tlas_s.get(tlas_id).get() + } + pub fn command_encoder_mark_acceleration_structures_built( &self, command_encoder_id: CommandEncoderId, @@ -73,7 +86,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with( + cmd_buf_data.with_buffer( |cmd_buf_data| -> Result<(), BuildAccelerationStructureError> { let device = &cmd_enc.device; device.check_is_valid()?; @@ -161,115 +174,118 @@ impl Global { .collect(); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| { - let blas_iter = trace_blas.iter().map(|blas_entry| { - let geometries = match &blas_entry.geometries { - TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { - size: &tg.size, - vertex_buffer: tg.vertex_buffer, - index_buffer: tg.index_buffer, - transform_buffer: tg.transform_buffer, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - first_index: tg.first_index, - transform_buffer_offset: tg.transform_buffer_offset, - }); - BlasGeometries::TriangleGeometries(Box::new(iter)) - } - }; - BlasBuildEntry { - blas_id: blas_entry.blas_id, - geometries, - } + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(crate::command::Command::BuildAccelerationStructures { + blas: trace_blas.clone(), + tlas: trace_tlas.clone(), }); + } - let tlas_iter = trace_tlas.iter().map(|tlas_package| { - let instances = tlas_package.instances.iter().map(|instance| { - instance.as_ref().map(|instance| TlasInstance { - blas_id: instance.blas_id, - transform: &instance.transform, - custom_data: instance.custom_data, - mask: instance.mask, + cmd_buf_data.push_with(|| -> Result<_, BuildAccelerationStructureError> { + let blas = trace_blas + .iter() + .map(|blas_entry| { + let geometries = match &blas_entry.geometries { + TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { + let tri_geo = triangle_geometries + .iter() + .map(|tg| { + Ok(ArcBlasTriangleGeometry { + size: tg.size.clone(), + vertex_buffer: self.resolve_buffer_id(tg.vertex_buffer)?, + index_buffer: tg + .index_buffer + .map(|id| self.resolve_buffer_id(id)) + .transpose()?, + transform_buffer: tg + .transform_buffer + .map(|id| self.resolve_buffer_id(id)) + .transpose()?, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + first_index: tg.first_index, + transform_buffer_offset: tg.transform_buffer_offset, + }) + }) + .collect::<Result<_, BuildAccelerationStructureError>>()?; + ArcBlasGeometries::TriangleGeometries(tri_geo) + } + }; + Ok(ArcBlasBuildEntry { + blas: self.resolve_blas_id(blas_entry.blas_id)?, + geometries, }) - }); - TlasPackage { - tlas_id: tlas_package.tlas_id, - instances: Box::new(instances), - lowest_unmodified: tlas_package.lowest_unmodified, - } - }); + }) + .collect::<Result<_, BuildAccelerationStructureError>>()?; + + let tlas = trace_tlas + .iter() + .map(|tlas_package| { + let instances = tlas_package + .instances + .iter() + .map(|instance| { + instance + .as_ref() + .map(|instance| { + Ok(ArcTlasInstance { + blas: self.resolve_blas_id(instance.blas_id)?, + transform: instance.transform, + custom_data: instance.custom_data, + mask: instance.mask, + }) + }) + .transpose() + }) + .collect::<Result<_, BuildAccelerationStructureError>>()?; + Ok(ArcTlasPackage { + tlas: self.resolve_tlas_id(tlas_package.tlas_id)?, + instances, + lowest_unmodified: tlas_package.lowest_unmodified, + }) + }) + .collect::<Result<_, BuildAccelerationStructureError>>()?; - build_acceleration_structures( - cmd_buf_data, - hub, - &cmd_enc, - trace_blas.clone(), - trace_tlas.clone(), - blas_iter, - tlas_iter, - ) + Ok(ArcCommand::BuildAccelerationStructures { blas, tlas }) }) } } -pub(crate) fn build_acceleration_structures<'a>( - cmd_buf_data: &'a mut CommandBufferMutable, - hub: &'a Hub, - cmd_enc: &'a Arc<CommandEncoder>, - trace_blas: Vec<TraceBlasBuildEntry>, - trace_tlas: Vec<TraceTlasPackage>, - blas_iter: impl Iterator<Item = BlasBuildEntry<'a>>, - tlas_iter: impl Iterator<Item = TlasPackage<'a>>, +pub(crate) fn build_acceleration_structures( + state: &mut EncodingState, + blas: Vec<ArcBlasBuildEntry>, + tlas: Vec<ArcTlasPackage>, ) -> Result<(), BuildAccelerationStructureError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(crate::command::Command::BuildAccelerationStructures { - blas: trace_blas, - tlas: trace_tlas, - }); - } - #[cfg(not(feature = "trace"))] - { - let _ = trace_blas; - let _ = trace_tlas; - } - - let device = &cmd_enc.device; - device.check_is_valid()?; - device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; + state + .device + .require_features(Features::EXPERIMENTAL_RAY_QUERY)?; let mut build_command = AsBuild::default(); let mut buf_storage = Vec::new(); iter_blas( - blas_iter, - cmd_buf_data, + blas.into_iter(), + state.tracker, &mut build_command, &mut buf_storage, - hub, )?; - let snatch_guard = device.snatchable_lock.read(); let mut input_barriers = Vec::<hal::BufferBarrier<dyn hal::DynBuffer>>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::new(); iter_buffers( + state, &mut buf_storage, - &snatch_guard, &mut input_barriers, - cmd_buf_data, &mut scratch_buffer_blas_size, &mut blas_storage, - hub, - device.alignments.ray_tracing_scratch_buffer_alignment, )?; - let mut tlas_lock_store = Vec::<(Option<TlasPackage>, Arc<Tlas>)>::new(); - - for package in tlas_iter { - let tlas = hub.tlas_s.get(package.tlas_id).get()?; - - cmd_buf_data.trackers.tlas_s.insert_single(tlas.clone()); + let mut tlas_lock_store = Vec::<(Option<ArcTlasPackage>, Arc<Tlas>)>::new(); + for package in tlas.into_iter() { + let tlas = package.tlas.clone(); + state.tracker.tlas_s.insert_single(tlas.clone()); tlas_lock_store.push((Some(package), tlas)) } @@ -283,7 +299,7 @@ pub(crate) fn build_acceleration_structures<'a>( let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += align_to( tlas.size_info.build_scratch_size as u32, - device.alignments.ray_tracing_scratch_buffer_alignment, + state.device.alignments.ray_tracing_scratch_buffer_alignment, ) as u64; let first_byte_index = instance_buffer_staging_source.len(); @@ -291,19 +307,18 @@ pub(crate) fn build_acceleration_structures<'a>( let mut dependencies = Vec::new(); let mut instance_count = 0; - for instance in package.instances.flatten() { + for instance in package.instances.into_iter().flatten() { if instance.custom_data >= (1u32 << 24u32) { return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( tlas.error_ident(), )); } - let blas = hub.blas_s.get(instance.blas_id).get()?; - - cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); + let blas = &instance.blas; + state.tracker.blas_s.insert_single(blas.clone()); - instance_buffer_staging_source.extend(device.raw().tlas_instance_to_bytes( + instance_buffer_staging_source.extend(state.device.raw().tlas_instance_to_bytes( hal::TlasInstance { - transform: *instance.transform, + transform: instance.transform, custom_data: instance.custom_data, mask: instance.mask, blas_address: blas.handle, @@ -366,7 +381,7 @@ pub(crate) fn build_acceleration_structures<'a>( return Ok(()); }; - let scratch_buffer = ScratchBuffer::new(device, scratch_size)?; + let scratch_buffer = ScratchBuffer::new(state.device, scratch_size)?; let scratch_buffer_barrier = hal::BufferBarrier::<dyn hal::DynBuffer> { buffer: scratch_buffer.raw(), @@ -396,7 +411,7 @@ pub(crate) fn build_acceleration_structures<'a>( mode: hal::AccelerationStructureBuildMode::Build, flags: tlas.flags, source_acceleration_structure: None, - destination_acceleration_structure: tlas.try_raw(&snatch_guard)?, + destination_acceleration_structure: tlas.try_raw(state.snatch_guard)?, scratch_buffer: scratch_buffer.raw(), scratch_buffer_offset: *scratch_buffer_offset, }) @@ -405,7 +420,7 @@ pub(crate) fn build_acceleration_structures<'a>( let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let raw_encoder = &mut state.raw_encoder; let mut blas_s_compactable = Vec::new(); let mut descriptors = Vec::new(); @@ -414,13 +429,13 @@ pub(crate) fn build_acceleration_structures<'a>( descriptors.push(map_blas( storage, scratch_buffer.raw(), - &snatch_guard, + state.snatch_guard, &mut blas_s_compactable, )?); } build_blas( - cmd_buf_raw, + *raw_encoder, blas_present, tlas_present, input_barriers, @@ -432,7 +447,7 @@ pub(crate) fn build_acceleration_structures<'a>( if tlas_present { let staging_buffer = if !instance_buffer_staging_source.is_empty() { let mut staging_buffer = StagingBuffer::new( - device, + state.device, wgt::BufferSize::new(instance_buffer_staging_source.len() as u64).unwrap(), )?; staging_buffer.write(&instance_buffer_staging_source); @@ -444,7 +459,7 @@ pub(crate) fn build_acceleration_structures<'a>( unsafe { if let Some(ref staging_buffer) = staging_buffer { - cmd_buf_raw.transition_buffers(&[hal::BufferBarrier::<dyn hal::DynBuffer> { + raw_encoder.transition_buffers(&[hal::BufferBarrier::<dyn hal::DynBuffer> { buffer: staging_buffer.raw(), usage: hal::StateTransition { from: BufferUses::MAP_WRITE, @@ -472,7 +487,7 @@ pub(crate) fn build_acceleration_structures<'a>( }, }); unsafe { - cmd_buf_raw.transition_buffers(&[hal::BufferBarrier::<dyn hal::DynBuffer> { + raw_encoder.transition_buffers(&[hal::BufferBarrier::<dyn hal::DynBuffer> { buffer: tlas.instance_buffer.as_ref(), usage: hal::StateTransition { from: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, @@ -484,9 +499,7 @@ pub(crate) fn build_acceleration_structures<'a>( dst_offset: 0, size, }; - cmd_buf_raw.copy_buffer_to_buffer( - // the range whose size we just checked end is at (at that point in time) instance_buffer_staging_source.len() - // and since instance_buffer_staging_source doesn't shrink we can un wrap this without a panic + raw_encoder.copy_buffer_to_buffer( staging_buffer.as_ref().unwrap().raw(), tlas.instance_buffer.as_ref(), &[temp], @@ -495,11 +508,11 @@ pub(crate) fn build_acceleration_structures<'a>( } unsafe { - cmd_buf_raw.transition_buffers(&instance_buffer_barriers); + raw_encoder.transition_buffers(&instance_buffer_barriers); - cmd_buf_raw.build_acceleration_structures(&tlas_descriptors); + raw_encoder.build_acceleration_structures(&tlas_descriptors); - cmd_buf_raw.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + raw_encoder.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { usage: hal::StateTransition { from: hal::AccelerationStructureUses::BUILD_OUTPUT, to: hal::AccelerationStructureUses::SHADER_INPUT, @@ -508,17 +521,17 @@ pub(crate) fn build_acceleration_structures<'a>( } if let Some(staging_buffer) = staging_buffer { - cmd_buf_data + state .temp_resources .push(TempResource::StagingBuffer(staging_buffer)); } } - cmd_buf_data + state .temp_resources .push(TempResource::ScratchBuffer(scratch_buffer)); - cmd_buf_data.as_actions.push(AsAction::Build(build_command)); + state.as_actions.push(AsAction::Build(build_command)); Ok(()) } @@ -600,23 +613,22 @@ impl CommandBufferMutable { } ///iterates over the blas iterator, and it's geometry, pushing the buffers into a storage vector (and also some validation). -fn iter_blas<'a>( - blas_iter: impl Iterator<Item = BlasBuildEntry<'a>>, - cmd_buf_data: &mut CommandBufferMutable, +fn iter_blas( + blas_iter: impl Iterator<Item = ArcBlasBuildEntry>, + tracker: &mut Tracker, build_command: &mut AsBuild, - buf_storage: &mut Vec<TriangleBufferStore<'a>>, - hub: &Hub, + buf_storage: &mut Vec<TriangleBufferStore>, ) -> Result<(), BuildAccelerationStructureError> { let mut temp_buffer = Vec::new(); for entry in blas_iter { - let blas = hub.blas_s.get(entry.blas_id).get()?; - cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); + let blas = &entry.blas; + tracker.blas_s.insert_single(blas.clone()); build_command.blas_s_built.push(blas.clone()); match entry.geometries { - BlasGeometries::TriangleGeometries(triangle_geometries) => { - for (i, mesh) in triangle_geometries.enumerate() { + ArcBlasGeometries::TriangleGeometries(triangle_geometries) => { + for (i, mesh) in triangle_geometries.into_iter().enumerate() { let size_desc = match &blas.sizes { wgt::BlasGeometrySizeDescriptors::Triangles { descriptors } => descriptors, }; @@ -715,13 +727,12 @@ fn iter_blas<'a>( blas.error_ident(), )); } - let vertex_buffer = hub.buffers.get(mesh.vertex_buffer).get()?; - let vertex_pending = cmd_buf_data.trackers.buffers.set_single( + let vertex_buffer = mesh.vertex_buffer.clone(); + let vertex_pending = tracker.buffers.set_single( &vertex_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); - let index_data = if let Some(index_id) = mesh.index_buffer { - let index_buffer = hub.buffers.get(index_id).get()?; + let index_data = if let Some(index_buffer) = mesh.index_buffer { if mesh.first_index.is_none() || mesh.size.index_count.is_none() || mesh.size.index_count.is_none() @@ -730,7 +741,7 @@ fn iter_blas<'a>( index_buffer.error_ident(), )); } - let data = cmd_buf_data.trackers.buffers.set_single( + let data = tracker.buffers.set_single( &index_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); @@ -738,7 +749,7 @@ fn iter_blas<'a>( } else { None }; - let transform_data = if let Some(transform_id) = mesh.transform_buffer { + let transform_data = if let Some(transform_buffer) = mesh.transform_buffer { if !blas .flags .contains(wgt::AccelerationStructureFlags::USE_TRANSFORM) @@ -747,13 +758,12 @@ fn iter_blas<'a>( blas.error_ident(), )); } - let transform_buffer = hub.buffers.get(transform_id).get()?; if mesh.transform_buffer_offset.is_none() { return Err(BuildAccelerationStructureError::MissingAssociatedData( transform_buffer.error_ident(), )); } - let data = cmd_buf_data.trackers.buffers.set_single( + let data = tracker.buffers.set_single( &transform_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); @@ -774,13 +784,19 @@ fn iter_blas<'a>( vertex_transition: vertex_pending, index_buffer_transition: index_data, transform_buffer_transition: transform_data, - geometry: mesh, + geometry: BlasTriangleGeometryInfo { + size: mesh.size, + first_vertex: mesh.first_vertex, + vertex_stride: mesh.vertex_stride, + first_index: mesh.first_index, + transform_buffer_offset: mesh.transform_buffer_offset, + }, ending_blas: None, }); } if let Some(last) = temp_buffer.last_mut() { - last.ending_blas = Some(blas); + last.ending_blas = Some(blas.clone()); buf_storage.append(&mut temp_buffer); } } @@ -790,29 +806,30 @@ fn iter_blas<'a>( } /// Iterates over the buffers generated in [iter_blas], convert the barriers into hal barriers, and the triangles into [hal::AccelerationStructureEntries] (and also some validation). -fn iter_buffers<'a, 'b>( - buf_storage: &'a mut Vec<TriangleBufferStore<'b>>, - snatch_guard: &'a SnatchGuard, - input_barriers: &mut Vec<hal::BufferBarrier<'a, dyn hal::DynBuffer>>, - cmd_buf_data: &mut CommandBufferMutable, +/// +/// `'buffers` is the lifetime of `&dyn hal::DynBuffer` in our working data, +/// i.e., needs to span until `build_acceleration_structures` finishes encoding. +/// `'snatch_guard` is the lifetime of the snatch lock acquisition. +fn iter_buffers<'snatch_guard: 'buffers, 'buffers>( + state: &mut EncodingState<'snatch_guard, '_>, + buf_storage: &'buffers mut Vec<TriangleBufferStore>, + input_barriers: &mut Vec<hal::BufferBarrier<'buffers, dyn hal::DynBuffer>>, scratch_buffer_blas_size: &mut u64, - blas_storage: &mut Vec<BlasStore<'a>>, - hub: &Hub, - ray_tracing_scratch_buffer_alignment: u32, + blas_storage: &mut Vec<BlasStore<'buffers>>, ) -> Result<(), BuildAccelerationStructureError> { let mut triangle_entries = Vec::<hal::AccelerationStructureTriangles<dyn hal::DynBuffer>>::new(); for buf in buf_storage { let mesh = &buf.geometry; let vertex_buffer = { - let vertex_buffer = buf.vertex_buffer.as_ref(); - let vertex_raw = vertex_buffer.try_raw(snatch_guard)?; + let vertex_raw = buf.vertex_buffer.as_ref().try_raw(state.snatch_guard)?; + let vertex_buffer = &buf.vertex_buffer; vertex_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = buf .vertex_transition .take() - .map(|pending| pending.into_hal(vertex_buffer, snatch_guard)) + .map(|pending| pending.into_hal(buf.vertex_buffer.as_ref(), state.snatch_guard)) { input_barriers.push(barrier); } @@ -826,9 +843,9 @@ fn iter_buffers<'a, 'b>( )); } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( vertex_buffer.initialization_status.read().create_action( - &hub.buffers.get(mesh.vertex_buffer).get()?, + vertex_buffer, vertex_buffer_offset ..(vertex_buffer_offset + mesh.size.vertex_count as u64 * mesh.vertex_stride), @@ -840,12 +857,12 @@ fn iter_buffers<'a, 'b>( let index_buffer = if let Some((ref mut index_buffer, ref mut index_pending)) = buf.index_buffer_transition { - let index_raw = index_buffer.try_raw(snatch_guard)?; + let index_raw = index_buffer.try_raw(state.snatch_guard)?; index_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = index_pending .take() - .map(|pending| pending.into_hal(index_buffer, snatch_guard)) + .map(|pending| pending.into_hal(index_buffer, state.snatch_guard)) { input_barriers.push(barrier); } @@ -867,7 +884,7 @@ fn iter_buffers<'a, 'b>( )); } - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( index_buffer.initialization_status.read().create_action( index_buffer, offset..(offset + index_buffer_size), @@ -886,12 +903,12 @@ fn iter_buffers<'a, 'b>( transform_buffer.error_ident(), )); } - let transform_raw = transform_buffer.try_raw(snatch_guard)?; + let transform_raw = transform_buffer.try_raw(state.snatch_guard)?; transform_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = transform_pending .take() - .map(|pending| pending.into_hal(transform_buffer, snatch_guard)) + .map(|pending| pending.into_hal(transform_buffer, state.snatch_guard)) { input_barriers.push(barrier); } @@ -912,7 +929,7 @@ fn iter_buffers<'a, 'b>( 48 + offset, )); } - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( transform_buffer.initialization_status.read().create_action( transform_buffer, offset..(offset + 48), @@ -952,7 +969,7 @@ fn iter_buffers<'a, 'b>( let scratch_buffer_offset = *scratch_buffer_blas_size; *scratch_buffer_blas_size += align_to( blas.size_info.build_scratch_size as u32, - ray_tracing_scratch_buffer_alignment, + state.device.alignments.ray_tracing_scratch_buffer_alignment, ) as u64; blas_storage.push(BlasStore { diff --git a/third_party/rust/wgpu-core/src/command/render.rs b/third_party/rust/wgpu-core/src/command/render.rs @@ -1,5 +1,6 @@ use alloc::{borrow::Cow, sync::Arc, vec::Vec}; -use core::{fmt, num::NonZeroU32, ops::Range, str}; +use core::{convert::Infallible, fmt, num::NonZeroU32, ops::Range, str}; +use smallvec::SmallVec; use arrayvec::ArrayVec; use thiserror::Error; @@ -11,8 +12,8 @@ use wgt::{ use crate::command::{ encoder::EncodingState, pass, pass_base, pass_try, validate_and_begin_occlusion_query, - validate_and_begin_pipeline_statistics_query, CommandBufferMutable, DebugGroupError, - EncoderStateError, InnerCommandEncoder, PassStateError, TimestampWritesError, + validate_and_begin_pipeline_statistics_query, ArcCommand, DebugGroupError, EncoderStateError, + InnerCommandEncoder, PassStateError, TimestampWritesError, }; use crate::pipeline::{RenderPipeline, VertexStep}; use crate::resource::RawResourceAccess; @@ -117,7 +118,7 @@ impl<V: Copy + Default> PassChannel<Option<V>> { } } -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum ResolvedPassChannel<V> { ReadOnly, Operational(wgt::Operations<V>), @@ -180,6 +181,11 @@ pub struct RenderPassColorAttachment<TV = id::TextureViewId> { pub type ArcRenderPassColorAttachment = RenderPassColorAttachment<Arc<TextureView>>; +// Avoid allocation in the common case that there is only one color attachment, +// but don't bloat `ArcCommand::RunRenderPass` excessively. +pub type ArcRenderPassColorAttachmentArray = + SmallVec<[Option<RenderPassColorAttachment<Arc<TextureView>>>; 1]>; + impl ArcRenderPassColorAttachment { fn hal_ops(&self) -> hal::AttachmentOps { load_hal_ops(self.load_op) | store_hal_ops(self.store_op) @@ -207,7 +213,7 @@ pub struct RenderPassDepthStencilAttachment { } /// Describes a depth/stencil attachment to a render pass. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct ArcRenderPassDepthStencilAttachment { /// The view to use as an attachment. pub view: Arc<TextureView>, @@ -494,7 +500,7 @@ impl VertexState { } } -struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { +struct State<'scope, 'snatch_guard, 'cmd_enc> { pipeline_flags: PipelineFlags, blend_constant: OptionalState, stencil_reference: u32, @@ -504,15 +510,13 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { info: RenderPassInfo, - pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc>, active_occlusion_query: Option<(Arc<QuerySet>, u32)>, active_pipeline_statistics_query: Option<(Arc<QuerySet>, u32)>, } -impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> - State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> -{ +impl<'scope, 'snatch_guard, 'cmd_enc> State<'scope, 'snatch_guard, 'cmd_enc> { fn is_ready(&self, family: DrawCommandFamily) -> Result<(), DrawError> { if let Some(pipeline) = self.pipeline.as_ref() { self.pass.binder.check_compatibility(pipeline.as_ref())?; @@ -953,14 +957,11 @@ impl RenderPassInfo { fn start( device: &Arc<Device>, hal_label: Option<&str>, - color_attachments: ArrayVec< - Option<ArcRenderPassColorAttachment>, - { hal::MAX_COLOR_ATTACHMENTS }, - >, + color_attachments: &[Option<ArcRenderPassColorAttachment>], mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>, mut timestamp_writes: Option<ArcPassTimestampWrites>, mut occlusion_query_set: Option<Arc<QuerySet>>, - encoder: &mut InnerCommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, pending_query_resets: &mut QueryResetMap, @@ -1422,7 +1423,6 @@ impl RenderPassInfo { }; unsafe { encoder - .raw .begin_render_pass(&hal_desc) .map_err(|e| device.handle_hal_error(e))?; }; @@ -1438,9 +1438,9 @@ impl RenderPassInfo { if let Some(at) = depth_stencil_attachment.take() { trackers.views.insert_single(at.view.clone()); } - for at in color_attachments.into_iter().flatten() { + for at in color_attachments.iter().flatten() { trackers.views.insert_single(at.view.clone()); - if let Some(resolve_target) = at.resolve_target { + if let Some(resolve_target) = at.resolve_target.clone() { trackers.views.insert_single(resolve_target); } } @@ -1740,7 +1740,7 @@ impl Global { pub fn render_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, - base: BasePass<super::RenderCommand, core::convert::Infallible>, + base: BasePass<super::RenderCommand, Infallible>, color_attachments: &[Option<RenderPassColorAttachment>], depth_stencil_attachment: Option<&RenderPassDepthStencilAttachment>, timestamp_writes: Option<&PassTimestampWrites>, @@ -1815,87 +1815,97 @@ impl Global { let cmd_enc = pass.parent.take().ok_or(EncoderStateError::Ended)?; let mut cmd_buf_data = cmd_enc.data.lock(); - if let Some(err) = pass.base.error.take() { - if matches!( - err, - RenderPassError { - inner: RenderPassErrorInner::EncoderState(EncoderStateError::Ended), - scope: _, - } - ) { - // If the encoder was already finished at time of pass creation, - // then it was not put in the locked state, so we need to - // generate a validation error here due to the encoder not being - // locked. The encoder already has a copy of the error. - return Err(EncoderStateError::Ended); - } else { - // If the pass is invalid, invalidate the parent encoder and return. - // Since we do not track the state of an invalid encoder, it is not - // necessary to unlock it. - cmd_buf_data.invalidate(err); - return Ok(()); - } + cmd_buf_data.unlock_encoder()?; + + let base = pass.base.take(); + + if matches!( + base, + Err(RenderPassError { + inner: RenderPassErrorInner::EncoderState(EncoderStateError::Ended), + scope: _, + }) + ) { + // If the encoder was already finished at time of pass creation, + // then it was not put in the locked state, so we need to + // generate a validation error here and now due to the encoder not + // being locked. The encoder already holds an error from when the + // pass was opened, or earlier. + // + // All other errors are propagated to the encoder within `push_with`, + // and will be reported later. + return Err(EncoderStateError::Ended); } - cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), RenderPassError> { - encode_render_pass(cmd_buf_data, &cmd_enc, pass) + cmd_buf_data.push_with(|| -> Result<_, RenderPassError> { + Ok(ArcCommand::RunRenderPass { + pass: base?, + color_attachments: SmallVec::from(pass.color_attachments.as_slice()), + depth_stencil_attachment: pass.depth_stencil_attachment.take(), + timestamp_writes: pass.timestamp_writes.take(), + occlusion_query_set: pass.occlusion_query_set.take(), + }) }) } } -fn encode_render_pass( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc<CommandEncoder>, - pass: &mut RenderPass, +pub(super) fn encode_render_pass( + parent_state: &mut EncodingState<InnerCommandEncoder>, + mut base: BasePass<ArcRenderCommand, Infallible>, + color_attachments: ArcRenderPassColorAttachmentArray, + mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>, + mut timestamp_writes: Option<ArcPassTimestampWrites>, + occlusion_query_set: Option<Arc<QuerySet>>, ) -> Result<(), RenderPassError> { let pass_scope = PassErrorScope::Pass; - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; - let snatch_guard = &device.snatchable_lock.read(); - - let base = &mut pass.base; + let device = parent_state.device; let mut indirect_draw_validation_batcher = crate::indirect_validation::DrawBatcher::new(); - let (scope, pending_discard_init_fixups, mut pending_query_resets) = { - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; - let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; - let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; - - // We automatically keep extending command buffers over time, and because - // we want to insert a command buffer _before_ what we're about to record, - // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - encoder - .open_pass(base.label.as_deref()) - .map_pass_err(pass_scope)?; + // We automatically keep extending command buffers over time, and because + // we want to insert a command buffer _before_ what we're about to record, + // we need to make sure to close the previous one. + parent_state + .raw_encoder + .close_if_open() + .map_pass_err(pass_scope)?; + let raw_encoder = parent_state + .raw_encoder + .open_pass(base.label.as_deref()) + .map_pass_err(pass_scope)?; + let (scope, pending_discard_init_fixups, mut pending_query_resets) = { let mut pending_query_resets = QueryResetMap::new(); let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); let info = RenderPassInfo::start( device, hal_label(base.label.as_deref(), device.instance_flags), - pass.color_attachments.take(), - pass.depth_stencil_attachment.take(), - pass.timestamp_writes.take(), + &color_attachments, + depth_stencil_attachment.take(), + timestamp_writes.take(), // Still needed down the line. // TODO(wumpf): by restructuring the code, we could get rid of some of this Arc clone. - pass.occlusion_query_set.clone(), - encoder, - tracker, - texture_memory_actions, + occlusion_query_set.clone(), + raw_encoder, + parent_state.tracker, + parent_state.texture_memory_actions, &mut pending_query_resets, &mut pending_discard_init_fixups, - snatch_guard, + parent_state.snatch_guard, ) .map_pass_err(pass_scope)?; let indices = &device.tracker_indices; - tracker.buffers.set_size(indices.buffers.size()); - tracker.textures.set_size(indices.textures.size()); + parent_state + .tracker + .buffers + .set_size(indices.buffers.size()); + parent_state + .tracker + .textures + .set_size(indices.textures.size()); let mut debug_scope_depth = 0; @@ -1912,14 +1922,15 @@ fn encode_render_pass( pass: pass::PassState { base: EncodingState { device, - raw_encoder: encoder.raw.as_mut(), - tracker, - buffer_memory_init_actions, - texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data + raw_encoder, + tracker: parent_state.tracker, + buffer_memory_init_actions: parent_state.buffer_memory_init_actions, + texture_memory_actions: parent_state.texture_memory_actions, + as_actions: parent_state.as_actions, + temp_resources: parent_state.temp_resources, + indirect_draw_validation_resources: parent_state .indirect_draw_validation_resources, - snatch_guard, + snatch_guard: parent_state.snatch_guard, debug_scope_depth: &mut debug_scope_depth, }, pending_discard_init_fixups, @@ -1946,7 +1957,7 @@ fn encode_render_pass( let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::<RenderPassErrorInner>( &mut state.pass, - cmd_enc.as_ref(), + device, &base.dynamic_offsets, index, num_dynamic_offsets, @@ -1957,7 +1968,7 @@ fn encode_render_pass( } ArcRenderCommand::SetPipeline(pipeline) => { let scope = PassErrorScope::SetPipelineRender; - set_pipeline(&mut state, cmd_enc, pipeline).map_pass_err(scope)?; + set_pipeline(&mut state, device, pipeline).map_pass_err(scope)?; } ArcRenderCommand::SetIndexBuffer { buffer, @@ -1966,7 +1977,7 @@ fn encode_render_pass( size, } => { let scope = PassErrorScope::SetIndexBuffer; - set_index_buffer(&mut state, cmd_enc, buffer, index_format, offset, size) + set_index_buffer(&mut state, device, buffer, index_format, offset, size) .map_pass_err(scope)?; } ArcRenderCommand::SetVertexBuffer { @@ -1976,7 +1987,7 @@ fn encode_render_pass( size, } => { let scope = PassErrorScope::SetVertexBuffer; - set_vertex_buffer(&mut state, cmd_enc, slot, buffer, offset, size) + set_vertex_buffer(&mut state, device, slot, buffer, offset, size) .map_pass_err(scope)?; } ArcRenderCommand::SetBlendConstant(ref color) => { @@ -2087,7 +2098,7 @@ fn encode_render_pass( multi_draw_indirect( &mut state, &mut indirect_draw_validation_batcher, - cmd_enc, + device, buffer, offset, count, @@ -2109,7 +2120,7 @@ fn encode_render_pass( }; multi_draw_indirect_count( &mut state, - cmd_enc, + device, buffer, offset, count_buffer, @@ -2137,7 +2148,7 @@ fn encode_render_pass( let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::<RenderPassErrorInner>( &mut state.pass, - cmd_enc.as_ref(), + device, Some(&mut pending_query_resets), query_set, query_index, @@ -2148,8 +2159,7 @@ fn encode_render_pass( api_log!("RenderPass::begin_occlusion_query {query_index}"); let scope = PassErrorScope::BeginOcclusionQuery; - let query_set = pass - .occlusion_query_set + let query_set = occlusion_query_set .clone() .ok_or(RenderPassErrorInner::MissingOcclusionQuerySet) .map_pass_err(scope)?; @@ -2188,7 +2198,7 @@ fn encode_render_pass( query_set, state.pass.base.raw_encoder, &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), + device, query_index, Some(&mut pending_query_resets), &mut state.active_pipeline_statistics_query, @@ -2210,7 +2220,7 @@ fn encode_render_pass( execute_bundle( &mut state, &mut indirect_draw_validation_batcher, - cmd_enc, + device, bundle, ) .map_pass_err(scope)?; @@ -2240,12 +2250,12 @@ fn encode_render_pass( let pending_discard_init_fixups = state.pass.pending_discard_init_fixups; - encoder.close().map_pass_err(pass_scope)?; + parent_state.raw_encoder.close().map_pass_err(pass_scope)?; (trackers, pending_discard_init_fixups, pending_query_resets) }; - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; + let encoder = &mut parent_state.raw_encoder; + let tracker = &mut parent_state.tracker; { let transit = encoder @@ -2259,22 +2269,27 @@ fn encode_render_pass( pending_discard_init_fixups.into_iter(), transit, &mut tracker.textures, - &cmd_enc.device, - snatch_guard, + device, + parent_state.snatch_guard, ); pending_query_resets.reset_queries(transit); - CommandEncoder::insert_barriers_from_scope(transit, tracker, &scope, snatch_guard); + CommandEncoder::insert_barriers_from_scope( + transit, + tracker, + &scope, + parent_state.snatch_guard, + ); if let Some(ref indirect_validation) = device.indirect_validation { indirect_validation .draw .inject_validation_pass( device, - snatch_guard, - &mut cmd_buf_data.indirect_draw_validation_resources, - &mut cmd_buf_data.temp_resources, + parent_state.snatch_guard, + parent_state.indirect_draw_validation_resources, + parent_state.temp_resources, transit, indirect_draw_validation_batcher, ) @@ -2289,7 +2304,7 @@ fn encode_render_pass( fn set_pipeline( state: &mut State, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, pipeline: Arc<RenderPipeline>, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_pipeline {}", pipeline.error_ident()); @@ -2304,7 +2319,7 @@ fn set_pipeline( .insert_single(pipeline) .clone(); - pipeline.same_device_as(cmd_enc.as_ref())?; + pipeline.same_device(device)?; state .info @@ -2359,7 +2374,7 @@ fn set_pipeline( // This function is duplicative of `bundle::set_index_buffer`. fn set_index_buffer( state: &mut State, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, buffer: Arc<crate::resource::Buffer>, index_format: IndexFormat, offset: u64, @@ -2373,7 +2388,7 @@ fn set_index_buffer( .buffers .merge_single(&buffer, wgt::BufferUses::INDEX)?; - buffer.same_device_as(cmd_enc.as_ref())?; + buffer.same_device(device)?; buffer.check_usage(BufferUsages::INDEX)?; @@ -2411,7 +2426,7 @@ fn set_index_buffer( // This function is duplicative of `render::set_vertex_buffer`. fn set_vertex_buffer( state: &mut State, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, slot: u32, buffer: Arc<crate::resource::Buffer>, offset: u64, @@ -2428,7 +2443,7 @@ fn set_vertex_buffer( .buffers .merge_single(&buffer, wgt::BufferUses::VERTEX)?; - buffer.same_device_as(cmd_enc.as_ref())?; + buffer.same_device(device)?; let max_vertex_buffers = state.pass.base.device.limits.max_vertex_buffers; if slot >= max_vertex_buffers { @@ -2688,7 +2703,7 @@ fn draw_mesh_tasks( fn multi_draw_indirect( state: &mut State, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, indirect_buffer: Arc<crate::resource::Buffer>, offset: u64, count: u32, @@ -2707,7 +2722,7 @@ fn multi_draw_indirect( .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; - indirect_buffer.same_device_as(cmd_enc.as_ref())?; + indirect_buffer.same_device(device)?; indirect_buffer.check_usage(BufferUsages::INDIRECT)?; indirect_buffer.check_destroyed(state.pass.base.snatch_guard)?; @@ -2866,7 +2881,7 @@ fn multi_draw_indirect( fn multi_draw_indirect_count( state: &mut State, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, indirect_buffer: Arc<crate::resource::Buffer>, offset: u64, count_buffer: Arc<crate::resource::Buffer>, @@ -2895,8 +2910,8 @@ fn multi_draw_indirect_count( .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; - indirect_buffer.same_device_as(cmd_enc.as_ref())?; - count_buffer.same_device_as(cmd_enc.as_ref())?; + indirect_buffer.same_device(device)?; + count_buffer.same_device(device)?; state .pass @@ -2989,14 +3004,14 @@ fn multi_draw_indirect_count( fn execute_bundle( state: &mut State, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, - cmd_enc: &Arc<CommandEncoder>, + device: &Arc<Device>, bundle: Arc<super::RenderBundle>, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::execute_bundle {}", bundle.error_ident()); let bundle = state.pass.base.tracker.bundles.insert_single(bundle); - bundle.same_device_as(cmd_enc.as_ref())?; + bundle.same_device(device)?; state .info diff --git a/third_party/rust/wgpu-core/src/command/transfer.rs b/third_party/rust/wgpu-core/src/command/transfer.rs @@ -12,10 +12,12 @@ use wgt::{ use crate::command::Command as TraceCommand; use crate::{ api_log, - command::{clear_texture, CommandEncoderError, EncoderStateError}, - device::{Device, MissingDownlevelFlags}, + command::{ + clear_texture, encoder::EncodingState, ArcCommand, CommandEncoderError, EncoderStateError, + }, + device::MissingDownlevelFlags, global::Global, - id::{BufferId, CommandEncoderId}, + id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, @@ -24,13 +26,12 @@ use crate::{ Buffer, MissingBufferUsageError, MissingTextureUsageError, ParentDevice, RawResourceAccess, Texture, TextureErrorDimension, }, - snatch::SnatchGuard, }; -use super::{ClearError, CommandBufferMutable}; +use super::ClearError; -use super::TexelCopyBufferInfo; -use super::TexelCopyTextureInfo; +type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo<BufferId>; +type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo<Arc<Texture>>; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum CopySide { @@ -629,13 +630,11 @@ pub(crate) fn validate_copy_within_same_texture<T>( } fn handle_texture_init( + state: &mut EncodingState, init_kind: MemoryInitKind, - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, copy_texture: &TexelCopyTextureInfo, copy_size: &Extent3d, texture: &Arc<Texture>, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), ClearError> { let init_action = TextureInitTrackerAction { texture: texture.clone(), @@ -648,13 +647,12 @@ fn handle_texture_init( }; // Register the init action. - let immediate_inits = cmd_buf_data + let immediate_inits = state .texture_memory_actions .register_init_action(&{ init_action }); // In rare cases we may need to insert an init operation immediately onto the command buffer. if !immediate_inits.is_empty() { - let cmd_buf_raw = cmd_buf_data.encoder.open()?; for init in immediate_inits { clear_texture( &init.texture, @@ -662,12 +660,12 @@ fn handle_texture_init( mip_range: init.mip_level..(init.mip_level + 1), layer_range: init.layer..(init.layer + 1), }, - cmd_buf_raw, - &mut cmd_buf_data.trackers.textures, - &device.alignments, - device.zero_buffer.as_ref(), - snatch_guard, - device.instance_flags, + state.raw_encoder, + &mut state.tracker.textures, + &state.device.alignments, + state.device.zero_buffer.as_ref(), + state.snatch_guard, + state.device.instance_flags, )?; } } @@ -680,21 +678,17 @@ fn handle_texture_init( /// Ensure the source texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_src_texture_init( - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, + state: &mut EncodingState, source: &TexelCopyTextureInfo, copy_size: &Extent3d, texture: &Arc<Texture>, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { handle_texture_init( + state, MemoryInitKind::NeedsInitializedMemory, - cmd_buf_data, - device, source, copy_size, texture, - snatch_guard, )?; Ok(()) } @@ -704,12 +698,10 @@ fn handle_src_texture_init( /// Ensure the destination texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_dst_texture_init( - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, - destination: &TexelCopyTextureInfo, + state: &mut EncodingState, + destination: &wgt::TexelCopyTextureInfo<Arc<Texture>>, copy_size: &Extent3d, texture: &Arc<Texture>, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { // Attention: If we don't write full texture subresources, we need to a full // clear first since we don't track subrects. This means that in rare cases @@ -725,15 +717,7 @@ fn handle_dst_texture_init( MemoryInitKind::ImplicitlyInitialized }; - handle_texture_init( - dst_init_kind, - cmd_buf_data, - device, - destination, - copy_size, - texture, - snatch_guard, - )?; + handle_texture_init(state, dst_init_kind, destination, copy_size, texture)?; Ok(()) } @@ -742,9 +726,8 @@ fn handle_dst_texture_init( /// Ensures that the transfer will not read from uninitialized memory, and updates /// the initialization state information to reflect the transfer. fn handle_buffer_init( - cmd_buf_data: &mut CommandBufferMutable, - info: &TexelCopyBufferInfo, - buffer: &Arc<Buffer>, + state: &mut EncodingState, + info: &wgt::TexelCopyBufferInfo<Arc<Buffer>>, direction: CopySide, required_buffer_bytes_in_copy: BufferAddress, is_contiguous: bool, @@ -752,6 +735,7 @@ fn handle_buffer_init( const ALIGN_SIZE: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT; const ALIGN_MASK: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT - 1; + let buffer = &info.buffer; let start = info.layout.offset; let end = info.layout.offset + required_buffer_bytes_in_copy; if !is_contiguous || direction == CopySide::Source { @@ -767,13 +751,13 @@ fn handle_buffer_init( // Adjust the start/end outwards to 4B alignment. let aligned_start = start & !ALIGN_MASK; let aligned_end = (end + ALIGN_MASK) & !ALIGN_MASK; - cmd_buf_data.buffer_memory_init_actions.extend( - buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(buffer.initialization_status.read().create_action( buffer, aligned_start..aligned_end, MemoryInitKind::NeedsInitializedMemory, - ), - ); + )); } else { // If the transfer will write a contiguous region of the buffer, then we // don't need to initialize that region. @@ -787,7 +771,7 @@ fn handle_buffer_init( let aligned_start = (start + ALIGN_MASK) & !ALIGN_MASK; let aligned_end = end & !ALIGN_MASK; if aligned_start != start { - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_start - ALIGN_SIZE..aligned_start, @@ -796,7 +780,7 @@ fn handle_buffer_init( ); } if aligned_start != aligned_end { - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_start..aligned_end, @@ -810,7 +794,7 @@ fn handle_buffer_init( // final size of the buffer. The final size of the buffer is not // readily available, but was rounded up to COPY_BUFFER_ALIGNMENT, // so no overrun is possible. - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_end..aligned_end + ALIGN_SIZE, @@ -840,17 +824,26 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_buffer_to_buffer( - cmd_buf_data, - hub, - &cmd_enc, - source, - source_offset, - destination, - destination_offset, + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyBufferToBuffer { + src: source, + src_offset: source_offset, + dst: destination, + dst_offset: destination_offset, size, - ) + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyBufferToBuffer { + src: self.resolve_buffer_id(source)?, + src_offset: source_offset, + dst: self.resolve_buffer_id(destination)?, + dst_offset: destination_offset, + size, + }) }) } @@ -858,7 +851,7 @@ impl Global { &self, command_encoder_id: CommandEncoderId, source: &TexelCopyBufferInfo, - destination: &TexelCopyTextureInfo, + destination: &wgt::TexelCopyTextureInfo<TextureId>, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { profiling::scope!("CommandEncoder::copy_buffer_to_texture"); @@ -868,19 +861,39 @@ impl Global { destination.texture ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_buffer_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyBufferToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyBufferToTexture { + src: wgt::TexelCopyBufferInfo::<Arc<Buffer>> { + buffer: self.resolve_buffer_id(source.buffer)?, + layout: source.layout, + }, + dst: wgt::TexelCopyTextureInfo::<Arc<Texture>> { + texture: self.resolve_texture_id(destination.texture)?, + mip_level: destination.mip_level, + origin: destination.origin, + aspect: destination.aspect, + }, + size: *copy_size, + }) }) } pub fn command_encoder_copy_texture_to_buffer( &self, command_encoder_id: CommandEncoderId, - source: &TexelCopyTextureInfo, + source: &wgt::TexelCopyTextureInfo<TextureId>, destination: &TexelCopyBufferInfo, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { @@ -891,20 +904,40 @@ impl Global { destination.buffer ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_texture_to_buffer(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyTextureToBuffer { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyTextureToBuffer { + src: wgt::TexelCopyTextureInfo::<Arc<Texture>> { + texture: self.resolve_texture_id(source.texture)?, + mip_level: source.mip_level, + origin: source.origin, + aspect: source.aspect, + }, + dst: wgt::TexelCopyBufferInfo::<Arc<Buffer>> { + buffer: self.resolve_buffer_id(destination.buffer)?, + layout: destination.layout, + }, + size: *copy_size, + }) }) } pub fn command_encoder_copy_texture_to_texture( &self, command_encoder_id: CommandEncoderId, - source: &TexelCopyTextureInfo, - destination: &TexelCopyTextureInfo, + source: &wgt::TexelCopyTextureInfo<TextureId>, + destination: &wgt::TexelCopyTextureInfo<TextureId>, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { profiling::scope!("CommandEncoder::copy_texture_to_texture"); @@ -914,76 +947,76 @@ impl Global { destination.texture ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_texture_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyTextureToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyTextureToTexture { + src: wgt::TexelCopyTextureInfo { + texture: self.resolve_texture_id(source.texture)?, + mip_level: source.mip_level, + origin: source.origin, + aspect: source.aspect, + }, + dst: wgt::TexelCopyTextureInfo { + texture: self.resolve_texture_id(destination.texture)?, + mip_level: destination.mip_level, + origin: destination.origin, + aspect: destination.aspect, + }, + size: *copy_size, + }) }) } } -fn copy_buffer_to_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<super::CommandEncoder>, - source: BufferId, +pub(super) fn copy_buffer_to_buffer( + state: &mut EncodingState, + src_buffer: &Arc<Buffer>, source_offset: BufferAddress, - destination: BufferId, + dst_buffer: &Arc<Buffer>, destination_offset: BufferAddress, size: Option<BufferAddress>, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - if source == destination { + if src_buffer.is_equal(dst_buffer) { return Err(TransferError::SameSourceDestinationBuffer.into()); } - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToBuffer { - src: source, - src_offset: source_offset, - dst: destination, - dst_offset: destination_offset, - size, - }); - } - - let snatch_guard = device.snatchable_lock.read(); - - let src_buffer = hub.buffers.get(source).get()?; + src_buffer.same_device(state.device)?; - src_buffer.same_device_as(cmd_enc.as_ref())?; - - let src_pending = cmd_buf_data - .trackers + let src_pending = state + .tracker .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); + .set_single(src_buffer, wgt::BufferUses::COPY_SRC); - let src_raw = src_buffer.try_raw(&snatch_guard)?; + let src_raw = src_buffer.try_raw(state.snatch_guard)?; src_buffer .check_usage(BufferUsages::COPY_SRC) .map_err(TransferError::MissingBufferUsage)?; // expecting only a single barrier - let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); - - let dst_buffer = hub.buffers.get(destination).get()?; + let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer, state.snatch_guard)); - dst_buffer.same_device_as(cmd_enc.as_ref())?; + dst_buffer.same_device(state.device)?; - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + .set_single(dst_buffer, wgt::BufferUses::COPY_DST); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer .check_usage(BufferUsages::COPY_DST) .map_err(TransferError::MissingBufferUsage)?; - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_buffer, state.snatch_guard)); let (size, source_end_offset) = match size { Some(size) => (size, source_offset + size), @@ -999,7 +1032,8 @@ fn copy_buffer_to_buffer( if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { return Err(TransferError::UnalignedBufferOffset(destination_offset).into()); } - if !device + if !state + .device .downlevel .flags .contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER) @@ -1046,64 +1080,51 @@ fn copy_buffer_to_buffer( } // Make sure source is initialized memory and mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( + dst_buffer, destination_offset..(destination_offset + size), MemoryInitKind::ImplicitlyInitialized, - ), - ); - cmd_buf_data.buffer_memory_init_actions.extend( - src_buffer.initialization_status.read().create_action( - &src_buffer, + )); + state + .buffer_memory_init_actions + .extend(src_buffer.initialization_status.read().create_action( + src_buffer, source_offset..(source_offset + size), MemoryInitKind::NeedsInitializedMemory, - ), - ); + )); let region = hal::BufferCopy { src_offset: source_offset, dst_offset: destination_offset, size: wgt::BufferSize::new(size).unwrap(), }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; let barriers = src_barrier .into_iter() .chain(dst_barrier) .collect::<Vec<_>>(); unsafe { - cmd_buf_raw.transition_buffers(&barriers); - cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); + state.raw_encoder.transition_buffers(&barriers); + state + .raw_encoder + .copy_buffer_to_buffer(src_raw, dst_raw, &[region]); } Ok(()) } -fn copy_buffer_to_texture( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<super::CommandEncoder>, - source: &TexelCopyBufferInfo, - destination: &TexelCopyTextureInfo, +pub(super) fn copy_buffer_to_texture( + state: &mut EncodingState, + source: &wgt::TexelCopyBufferInfo<Arc<Buffer>>, + destination: &wgt::TexelCopyTextureInfo<Arc<Texture>>, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } - - let dst_texture = hub.textures.get(destination.texture).get()?; - let src_buffer = hub.buffers.get(source.buffer).get()?; + let dst_texture = &destination.texture; + let src_buffer = &source.buffer; - dst_texture.same_device_as(cmd_enc.as_ref())?; - src_buffer.same_device_as(cmd_enc.as_ref())?; + dst_texture.same_device(state.device)?; + src_buffer.same_device(state.device)?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range( destination, @@ -1112,12 +1133,10 @@ fn copy_buffer_to_texture( copy_size, )?; - let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; - - let snatch_guard = device.snatchable_lock.read(); + let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, dst_texture)?; - let src_raw = src_buffer.try_raw(&snatch_guard)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; + let src_raw = src_buffer.try_raw(state.snatch_guard)?; + let dst_raw = dst_texture.try_raw(state.snatch_guard)?; if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { log::trace!("Ignoring copy_buffer_to_texture of size 0"); @@ -1127,30 +1146,23 @@ fn copy_buffer_to_texture( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; + handle_dst_texture_init(state, destination, copy_size, dst_texture)?; - let src_pending = cmd_buf_data - .trackers + let src_pending = state + .tracker .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); + .set_single(src_buffer, wgt::BufferUses::COPY_SRC); src_buffer .check_usage(BufferUsages::COPY_SRC) .map_err(TransferError::MissingBufferUsage)?; - let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); + let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer, state.snatch_guard)); - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); + let dst_pending = + state + .tracker + .textures + .set_single(dst_texture, dst_range, wgt::TextureUses::COPY_DST); dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; @@ -1179,15 +1191,15 @@ fn copy_buffer_to_texture( )?; if dst_texture.desc.format.is_depth_stencil_format() { - device + state + .device .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) .map_err(TransferError::from)?; } handle_buffer_init( - cmd_buf_data, + state, source, - &src_buffer, CopySide::Source, required_buffer_bytes_in_copy, is_contiguous, @@ -1207,50 +1219,35 @@ fn copy_buffer_to_texture( }) .collect::<Vec<_>>(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(&dst_barrier); - cmd_buf_raw.transition_buffers(src_barrier.as_slice()); - cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); + state.raw_encoder.transition_textures(&dst_barrier); + state.raw_encoder.transition_buffers(src_barrier.as_slice()); + state + .raw_encoder + .copy_buffer_to_texture(src_raw, dst_raw, ®ions); } Ok(()) } -fn copy_texture_to_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<super::CommandEncoder>, +pub(super) fn copy_texture_to_buffer( + state: &mut EncodingState, source: &TexelCopyTextureInfo, - destination: &TexelCopyBufferInfo, + destination: &wgt::TexelCopyBufferInfo<Arc<Buffer>>, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(list) = cmd_buf_data.trace_commands.as_mut() { - list.push(TraceCommand::CopyTextureToBuffer { - src: *source, - dst: *destination, - size: *copy_size, - }); - } - - let src_texture = hub.textures.get(source.texture).get()?; - let dst_buffer = hub.buffers.get(destination.buffer).get()?; + let src_texture = &source.texture; + let dst_buffer = &destination.buffer; - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_buffer.same_device_as(cmd_enc.as_ref())?; + src_texture.same_device(state.device)?; + dst_buffer.same_device(state.device)?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range(source, &src_texture.desc, CopySide::Source, copy_size)?; - let (src_range, src_base) = extract_texture_selector(source, copy_size, &src_texture)?; + let (src_range, src_base) = extract_texture_selector(source, copy_size, src_texture)?; - let snatch_guard = device.snatchable_lock.read(); - - let src_raw = src_texture.try_raw(&snatch_guard)?; + let src_raw = src_texture.try_raw(state.snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) .map_err(TransferError::MissingTextureUsage)?; @@ -1284,12 +1281,13 @@ fn copy_texture_to_buffer( )?; if src_texture.desc.format.is_depth_stencil_format() { - device + state + .device .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) .map_err(TransferError::from)?; } - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer .check_usage(BufferUsages::COPY_DST) .map_err(TransferError::MissingBufferUsage)?; @@ -1302,35 +1300,27 @@ fn copy_texture_to_buffer( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; + handle_src_texture_init(state, source, copy_size, src_texture)?; - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); + let src_pending = + state + .tracker + .textures + .set_single(src_texture, src_range, wgt::TextureUses::COPY_SRC); let src_barrier = src_pending .map(|pending| pending.into_hal(src_raw)) .collect::<Vec<_>>(); - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + .set_single(dst_buffer, wgt::BufferUses::COPY_DST); - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_buffer, state.snatch_guard)); handle_buffer_init( - cmd_buf_data, + state, destination, - &dst_buffer, CopySide::Destination, required_buffer_bytes_in_copy, is_contiguous, @@ -1349,43 +1339,31 @@ fn copy_texture_to_buffer( } }) .collect::<Vec<_>>(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.transition_textures(&src_barrier); - cmd_buf_raw.copy_texture_to_buffer(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.transition_textures(&src_barrier); + state.raw_encoder.copy_texture_to_buffer( + src_raw, + wgt::TextureUses::COPY_SRC, + dst_raw, + ®ions, + ); } Ok(()) } -fn copy_texture_to_texture( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc<super::CommandEncoder>, +pub(super) fn copy_texture_to_texture( + state: &mut EncodingState, source: &TexelCopyTextureInfo, destination: &TexelCopyTextureInfo, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - let snatch_guard = device.snatchable_lock.read(); - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyTextureToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } + let src_texture = &source.texture; + let dst_texture = &destination.texture; - let src_texture = hub.textures.get(source.texture).get()?; - let dst_texture = hub.textures.get(destination.texture).get()?; - - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_texture.same_device_as(cmd_enc.as_ref())?; + src_texture.same_device(state.device)?; + dst_texture.same_device(state.device)?; // src and dst texture format must be copy-compatible // https://gpuweb.github.io/gpuweb/#copy-compatible @@ -1407,7 +1385,7 @@ fn copy_texture_to_texture( copy_size, )?; - if Arc::as_ptr(&src_texture) == Arc::as_ptr(&dst_texture) { + if Arc::as_ptr(src_texture) == Arc::as_ptr(dst_texture) { validate_copy_within_same_texture( source, destination, @@ -1416,8 +1394,8 @@ fn copy_texture_to_texture( )?; } - let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, &src_texture)?; - let (dst_range, dst_tex_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; + let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, src_texture)?; + let (dst_range, dst_tex_base) = extract_texture_selector(destination, copy_size, dst_texture)?; let src_texture_aspects = hal::FormatAspects::from(src_texture.desc.format); let dst_texture_aspects = hal::FormatAspects::from(dst_texture.desc.format); if src_tex_base.aspect != src_texture_aspects { @@ -1438,28 +1416,14 @@ fn copy_texture_to_texture( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; + handle_src_texture_init(state, source, copy_size, src_texture)?; + handle_dst_texture_init(state, destination, copy_size, dst_texture)?; - let src_raw = src_texture.try_raw(&snatch_guard)?; + let src_raw = src_texture.try_raw(state.snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) .map_err(TransferError::MissingTextureUsage)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; + let dst_raw = dst_texture.try_raw(state.snatch_guard)?; dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; @@ -1469,11 +1433,11 @@ fn copy_texture_to_texture( return Ok(()); } - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); + let src_pending = + state + .tracker + .textures + .set_single(src_texture, src_range, wgt::TextureUses::COPY_SRC); //TODO: try to avoid this the collection. It's needed because both // `src_pending` and `dst_pending` try to hold `trackers.textures` mutably. @@ -1481,11 +1445,11 @@ fn copy_texture_to_texture( .map(|pending| pending.into_hal(src_raw)) .collect(); - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); + let dst_pending = + state + .tracker + .textures + .set_single(dst_texture, dst_range, wgt::TextureUses::COPY_DST); barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); let hal_copy_size = hal::CopyExtent { @@ -1520,10 +1484,14 @@ fn copy_texture_to_texture( } else { regions.collect::<Vec<_>>() }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(&barriers); - cmd_buf_raw.copy_texture_to_texture(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + state.raw_encoder.transition_textures(&barriers); + state.raw_encoder.copy_texture_to_texture( + src_raw, + wgt::TextureUses::COPY_SRC, + dst_raw, + ®ions, + ); } Ok(()) diff --git a/third_party/rust/wgpu-core/src/command/transition_resources.rs b/third_party/rust/wgpu-core/src/command/transition_resources.rs @@ -1,12 +1,14 @@ +use alloc::{sync::Arc, vec::Vec}; + use thiserror::Error; use wgt::error::{ErrorType, WebGpuError}; use crate::{ - command::{CommandEncoder, CommandEncoderError, EncoderStateError}, + command::{encoder::EncodingState, ArcCommand, CommandEncoder, EncoderStateError}, device::DeviceError, global::Global, id::{BufferId, CommandEncoderId, TextureId}, - resource::{InvalidResourceError, ParentDevice}, + resource::{Buffer, InvalidResourceError, ParentDevice, Texture}, track::ResourceUsageCompatibilityError, }; @@ -24,52 +26,70 @@ impl Global { // Lock command encoder for recording let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - // Get and lock device - let device = &cmd_enc.device; - device.check_is_valid()?; - let snatch_guard = &device.snatchable_lock.read(); - - let mut usage_scope = device.new_usage_scope(); - let indices = &device.tracker_indices; - usage_scope.buffers.set_size(indices.buffers.size()); - usage_scope.textures.set_size(indices.textures.size()); + cmd_buf_data.push_with(|| -> Result<_, TransitionResourcesError> { + Ok(ArcCommand::TransitionResources { + buffer_transitions: buffer_transitions + .map(|t| { + Ok(wgt::BufferTransition { + buffer: self.resolve_buffer_id(t.buffer)?, + state: t.state, + }) + }) + .collect::<Result<_, TransitionResourcesError>>()?, + texture_transitions: texture_transitions + .map(|t| { + Ok(wgt::TextureTransition { + texture: self.resolve_texture_id(t.texture)?, + selector: t.selector, + state: t.state, + }) + }) + .collect::<Result<_, TransitionResourcesError>>()?, + }) + }) + } +} - // Process buffer transitions - for buffer_transition in buffer_transitions { - let buffer = hub.buffers.get(buffer_transition.buffer).get()?; - buffer.same_device_as(cmd_enc.as_ref())?; +pub(crate) fn transition_resources( + state: &mut EncodingState, + buffer_transitions: Vec<wgt::BufferTransition<Arc<Buffer>>>, + texture_transitions: Vec<wgt::TextureTransition<Arc<Texture>>>, +) -> Result<(), TransitionResourcesError> { + let mut usage_scope = state.device.new_usage_scope(); + let indices = &state.device.tracker_indices; + usage_scope.buffers.set_size(indices.buffers.size()); + usage_scope.textures.set_size(indices.textures.size()); - usage_scope - .buffers - .merge_single(&buffer, buffer_transition.state)?; - } + // Process buffer transitions + for buffer_transition in buffer_transitions { + buffer_transition.buffer.same_device(state.device)?; - // Process texture transitions - for texture_transition in texture_transitions { - let texture = hub.textures.get(texture_transition.texture).get()?; - texture.same_device_as(cmd_enc.as_ref())?; + usage_scope + .buffers + .merge_single(&buffer_transition.buffer, buffer_transition.state)?; + } - unsafe { - usage_scope.textures.merge_single( - &texture, - texture_transition.selector, - texture_transition.state, - ) - }?; - } + // Process texture transitions + for texture_transition in texture_transitions { + texture_transition.texture.same_device(state.device)?; - // Record any needed barriers based on tracker data - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - CommandEncoder::insert_barriers_from_scope( - cmd_buf_raw, - &mut cmd_buf_data.trackers, - &usage_scope, - snatch_guard, - ); - Ok(()) - }) + unsafe { + usage_scope.textures.merge_single( + &texture_transition.texture, + texture_transition.selector, + texture_transition.state, + ) + }?; } + + // Record any needed barriers based on tracker data + CommandEncoder::insert_barriers_from_scope( + state.raw_encoder, + state.tracker, + &usage_scope, + state.snatch_guard, + ); + Ok(()) } /// Error encountered while attempting to perform [`Global::command_encoder_transition_resources`]. diff --git a/third_party/rust/wgpu-core/src/ray_tracing.rs b/third_party/rust/wgpu-core/src/ray_tracing.rs @@ -21,7 +21,7 @@ use crate::{ device::{DeviceError, MissingFeatures}, id::{BlasId, BufferId, TlasId}, resource::{ - Blas, BlasCompactCallback, BlasPrepareCompactResult, DestroyedResourceError, + Blas, BlasCompactCallback, BlasPrepareCompactResult, Buffer, DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, ResourceErrorIdent, Tlas, }, }; @@ -304,6 +304,7 @@ pub(crate) enum AsAction { UseTlas(Arc<Tlas>), } +/// Like [`BlasTriangleGeometry`], but with owned data. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceBlasTriangleGeometry { @@ -347,6 +348,55 @@ pub struct TraceTlasPackage { pub lowest_unmodified: u32, } +/// Like [`BlasTriangleGeometry`], but with `Arc`s. +#[derive(Debug, Clone)] +pub struct ArcBlasTriangleGeometry { + pub size: wgt::BlasTriangleGeometrySizeDescriptor, + pub vertex_buffer: Arc<Buffer>, + pub index_buffer: Option<Arc<Buffer>>, + pub transform_buffer: Option<Arc<Buffer>>, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub first_index: Option<u32>, + pub transform_buffer_offset: Option<BufferAddress>, +} + +/// [`BlasTriangleGeometry`], without the resources. +#[derive(Debug, Clone)] +pub struct BlasTriangleGeometryInfo { + pub size: wgt::BlasTriangleGeometrySizeDescriptor, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub first_index: Option<u32>, + pub transform_buffer_offset: Option<BufferAddress>, +} + +#[derive(Debug, Clone)] +pub enum ArcBlasGeometries { + TriangleGeometries(Vec<ArcBlasTriangleGeometry>), +} + +#[derive(Debug, Clone)] +pub struct ArcBlasBuildEntry { + pub blas: Arc<Blas>, + pub geometries: ArcBlasGeometries, +} + +#[derive(Debug, Clone)] +pub struct ArcTlasInstance { + pub blas: Arc<Blas>, + pub transform: [f32; 12], + pub custom_data: u32, + pub mask: u8, +} + +#[derive(Debug, Clone)] +pub struct ArcTlasPackage { + pub tlas: Arc<Tlas>, + pub instances: Vec<Option<ArcTlasInstance>>, + pub lowest_unmodified: u32, +} + #[derive(Clone, Debug, Error)] pub enum BlasPrepareCompactError { #[error(transparent)] diff --git a/third_party/rust/wgpu-hal/.cargo-checksum.json b/third_party/rust/wgpu-hal/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"8560c6ce168a377741bc9c3e8b87f1482825a304c8b3a52572ef17d22bed33e4","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","README.md":"cf9e84804a635e4a8a9fefc596be9da6bf7354dde0d105e27d56a12cb20dd8e3","build.rs":"e720cf033fecfdc7e4f34010af2a86340c99b8aaabf69559d32391521e25de6c","examples/halmark/main.rs":"171c7f68df3884f9db09ca9034e2842be5e608984613d067f1af548b7b68b0e7","examples/halmark/shader.wgsl":"26c256ec36d6f0e9a1647431ca772766bee4382d64eaa718ba7b488dcfb6bcca","examples/raw-gles.em.html":"70fbe68394a1a4522192de1dcfaf7d399f60d7bdf5de70b708f9bb0417427546","examples/raw-gles.rs":"5f4cfa893e99dfec559803bc513457793dcc549154c604385fb287f99a3ea675","examples/ray-traced-triangle/main.rs":"ac1a631a98afae34970bb4446b229961d1371debcb389c8fae96761e5f581d55","examples/ray-traced-triangle/shader.wgsl":"cc10caf92746724a71f6dd0dbc3a71e57b37c7d1d83278556805a535c0728a9d","src/auxil/dxgi/conv.rs":"3ca856c93916c0be714924ff077aa1f366be5557cc164210154d252e7e49fb77","src/auxil/dxgi/exception.rs":"7138831914a59dc7cbb71512068e9134144b9bc8f43312682edccb0b3ee24a48","src/auxil/dxgi/factory.rs":"81e479e550a09127384d8080e43d5f5bae8e8dda6082fe41a87bea8f872eb0f1","src/auxil/dxgi/mod.rs":"e6c5cc3b73bb97742135d6f35308c42f0822304764978fb8dabb0e848863352a","src/auxil/dxgi/name.rs":"ff942da0da1a497ee4d2be21604f7ba9fae963588105b3d1f63aae1a0c536e82","src/auxil/dxgi/result.rs":"e7a9dfb48d8ef8cbe58b28b1ace5caf7818ee50505ba3220bb0509e66ae469b7","src/auxil/dxgi/time.rs":"b6911800be3873cbe277b2534b3839c6f005f3d9a09341aace4752e207d584a2","src/auxil/mod.rs":"540b9250d9f0e0af709245ce1e284eaca15b27d47550b0ebba2a512da1666c48","src/auxil/renderdoc.rs":"94898f747476e269b2910d42e769f2bbb6be0cb466ad92f9d381f55799d2756e","src/dx12/adapter.rs":"85fcc7ad13a4b0f8b324f040261d53fcfb9d54ee947bc856b37fb458ea363844","src/dx12/command.rs":"813a4515185b0d218fffd361f247e53930feef7c676f944351c51bd7e3e988d5","src/dx12/conv.rs":"ef5fa91bbe8b044b7f7949452a04eefbf4b0d3a97f6d89665e021efae8568643","src/dx12/dcomp.rs":"53bde57557d80e571257f76933d66475a765e063d8b635675f9dd2563039a4c5","src/dx12/descriptor.rs":"ccd4feb6bd3e0a0ffc26142f8a81fca26180d0f50146b6eb2f670cbc89ea7064","src/dx12/device.rs":"8d59a6482f5a00e4e1c596b5e44acfa159a86112b64622f7b401ac2ce7e8834e","src/dx12/instance.rs":"75bddc3807756c691ede3ff944915e443a8bb2b5ac6d0d99babd4ed50d1e3fb9","src/dx12/mod.rs":"d52f3a5867a439d9e622e6427fc075dc80bfed8252333480d8874f8b49a29d9d","src/dx12/sampler.rs":"d18d243efe4fa667dbab5b75b5b91d47de94d441976d9f44a46a2b49ba38473d","src/dx12/shader_compilation.rs":"c901a797c69e08c8c0ec93ea37c5f31084eb21c26c7d703d7031f987f2243509","src/dx12/suballocation.rs":"014e9ec4a94519b877ad3adc2ea5d182aa6cdf502248009d28dc5833a9edb93c","src/dx12/types.rs":"3fc7619fc09303eb3c936d4ded6889f94ce9e8b9aa62742ce900baa1b1e1cca7","src/dx12/view.rs":"79b3f7331d9795e60f9b53023cbf0df46c3a05b1e8bd5c7bcca8acdd235b124f","src/dynamic/adapter.rs":"e93f7d082a3950c9e8ccff8a631d251c7598b4b25dda9fe6347dadfa3ba07829","src/dynamic/command.rs":"9635dea15d8a885011d2b8b6b9cc5ffe2126cc3f141f47f7aaf46e1f201abea9","src/dynamic/device.rs":"4c8368a5ba6947f982f16accef75e15cbef2dcb6e4bd5995783b7d6fdf131ff6","src/dynamic/instance.rs":"7b515c201e1ca24f24439544dbfa1d19ea1412a4f89bd803e009aed13b021e55","src/dynamic/mod.rs":"2577d3aef6441f5b42b427d80ba3cf7fee2a97b2fc12335a1fba383e8a79a9b2","src/dynamic/queue.rs":"d76abb4797e90253386d24584f186dbe1909e772560156b2e891fa043cfefbdc","src/dynamic/surface.rs":"4328c2fe86931f50aa00ac3d6982d0879b774eebf7a507903d1b1898c891fb4d","src/gles/adapter.rs":"7cbe1b3dda180d0eee69af3474308175dfb964db071ec9779baf21ffd641f679","src/gles/command.rs":"c13d50eeb1a4aaab367a3b4a7fe6c25c8c73377e68d0d8cc43791d1a7202d23b","src/gles/conv.rs":"de1ad6c07d26e8f9f3be8a7a51bca212e92fd5449aaa85c6ad9c37b91afa6994","src/gles/device.rs":"0ab205747f317d517204def9281cb3561241a53bb2233252adfb7581c015c1ba","src/gles/egl.rs":"2a336cd6bf3cc6660677ac2621f903c9dd72a1cf484d41c7b69c341b809844c4","src/gles/emscripten.rs":"316d2bb6f2a4bb126dbe68a223f7393399080d116b61c39504454acdf4f9cfaf","src/gles/fence.rs":"083cd49747aba6272002aba0b0c37e5768cdbc2a1b8bacd1a244ee905d3f7b0f","src/gles/mod.rs":"24a29ca8f7a5c3c7601d74b3fd8a9d4b402e7b794b6fd70bda36acf5960ae828","src/gles/queue.rs":"5152f5698a2998a55125d13f04788b960726fd4b49ae4d2ec8f9642c8825c7fd","src/gles/shaders/clear.frag":"9133ed8ed97d3641fbb6b5f5ea894a3554c629ccc1b80a5fc9221d7293aa1954","src/gles/shaders/clear.vert":"a543768725f4121ff2e9e1fb5b00644931e9d6f2f946c0ef01968afb5a135abd","src/gles/shaders/srgb_present.frag":"dd9a43c339a2fa4ccf7f6a1854c6f400cabf271a7d5e9230768e9f39d47f3ff5","src/gles/shaders/srgb_present.vert":"6e85d489403d80b81cc94790730bb53b309dfc5eeede8f1ea3412a660f31d357","src/gles/web.rs":"cb5940bf7b2381811675011b640040274f407a7d1908d0f82c813d6a9d3b00f7","src/gles/wgl.rs":"ed0cee8844447b461ed5340f81eb55bb051ceaac67a5768985318ceac133cbe4","src/lib.rs":"857e57ce6d1dc95f6b1aa05c30e52423ff488ed892b5ad1c010a14252633d436","src/metal/adapter.rs":"9184c7658efe5dd43224d23294ebd3fe98a19b0290c41703496de276dad5f996","src/metal/command.rs":"20bf613b67ccc043de6e8ad3f3d332bbb678cc06c1593cf1880083de090574ba","src/metal/conv.rs":"85e8168be334ba24d109575a0a7e91b2ad3459403173e99e5cdd5d977cc5c18f","src/metal/device.rs":"8988736987b280c8ae3dd1a9e1461d7f39a85b5241ce6074c3278be4e8fa881e","src/metal/layer_observer.rs":"8370a6e443d01739b951b8538ee719a03b69fc0cbac92c748db418fbcc8837b5","src/metal/mod.rs":"82d7e8b96ba04fab5b42722574e9f081def9e50c92dcc7d554d8111b9d0aa2a1","src/metal/surface.rs":"22dc6da86ac74b044b6498764920f0467bb5060f4dffb156b6c1e260db0c48b7","src/metal/time.rs":"c32d69f30e846dfcc0e39e01097fb80df63b2bebb6586143bb62494999850246","src/noop/buffer.rs":"b5edc5e2c52287dfbd4f619e36097ac233041eb9ab287b889b6ee477d740fa09","src/noop/command.rs":"3de99a1a260cfea2e6ca2e76797c1923cc26b069b08362c38798ce27cdc75543","src/noop/mod.rs":"85253d9c36fca50e14c562fb35928e69342bcd367a78d9c512d6ce15702c74a5","src/validation_canary.rs":"2e8f84e5f85671b3e55ddd410476171c762e34cbea315b37921cbb6ff18bfb4f","src/vulkan/adapter.rs":"dd4e44cdb4cc08e5b0e50f029c3ee8eed68fc42378e58284f92614f408e2055e","src/vulkan/command.rs":"22fd05428c141ce58000c8f3541d39195023ffdfb72c4b00379a5c50a3ecea82","src/vulkan/conv.rs":"c89394ae726b91e887867dd3d2ad188310ffe98771e745db02df32c080971518","src/vulkan/device.rs":"6a7883f459ec6b440107de3991466f2399b27560869289cd6ecddd946d018a5e","src/vulkan/drm.rs":"45f7bf1dd854688a65261e4674d80f90c997b193a162fd2ae658acf4e2003552","src/vulkan/instance.rs":"6740bc9ca240aa512509520d2b5a9cd2129330c413d94fce786b8301fa5f2202","src/vulkan/mod.rs":"ea0bc048993265f0e2ec7ff7dd67fe4b7fff20fa3a0ca2d6a1b291b92d053002","src/vulkan/sampler.rs":"f65729d6df5cce681b7756b3e48074017f0c7f42da69ca55e26cc723cd14ad59","src/vulkan/semaphore_list.rs":"102266d8e1b9f2ec1decf681bcc9e1a4cbff29533a258f2699fb6c573c434771"},"package":null} -\ No newline at end of file +{"files":{"Cargo.toml":"2518cac140b7be3931ec2cafcc838e8a7e90ff1912b859cca9cf6f7fddf39e92","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","README.md":"cf9e84804a635e4a8a9fefc596be9da6bf7354dde0d105e27d56a12cb20dd8e3","build.rs":"e720cf033fecfdc7e4f34010af2a86340c99b8aaabf69559d32391521e25de6c","examples/halmark/main.rs":"171c7f68df3884f9db09ca9034e2842be5e608984613d067f1af548b7b68b0e7","examples/halmark/shader.wgsl":"26c256ec36d6f0e9a1647431ca772766bee4382d64eaa718ba7b488dcfb6bcca","examples/raw-gles.em.html":"70fbe68394a1a4522192de1dcfaf7d399f60d7bdf5de70b708f9bb0417427546","examples/raw-gles.rs":"5f4cfa893e99dfec559803bc513457793dcc549154c604385fb287f99a3ea675","examples/ray-traced-triangle/main.rs":"ac1a631a98afae34970bb4446b229961d1371debcb389c8fae96761e5f581d55","examples/ray-traced-triangle/shader.wgsl":"cc10caf92746724a71f6dd0dbc3a71e57b37c7d1d83278556805a535c0728a9d","src/auxil/dxgi/conv.rs":"3ca856c93916c0be714924ff077aa1f366be5557cc164210154d252e7e49fb77","src/auxil/dxgi/exception.rs":"7138831914a59dc7cbb71512068e9134144b9bc8f43312682edccb0b3ee24a48","src/auxil/dxgi/factory.rs":"81e479e550a09127384d8080e43d5f5bae8e8dda6082fe41a87bea8f872eb0f1","src/auxil/dxgi/mod.rs":"e6c5cc3b73bb97742135d6f35308c42f0822304764978fb8dabb0e848863352a","src/auxil/dxgi/name.rs":"ff942da0da1a497ee4d2be21604f7ba9fae963588105b3d1f63aae1a0c536e82","src/auxil/dxgi/result.rs":"e7a9dfb48d8ef8cbe58b28b1ace5caf7818ee50505ba3220bb0509e66ae469b7","src/auxil/dxgi/time.rs":"b6911800be3873cbe277b2534b3839c6f005f3d9a09341aace4752e207d584a2","src/auxil/mod.rs":"540b9250d9f0e0af709245ce1e284eaca15b27d47550b0ebba2a512da1666c48","src/auxil/renderdoc.rs":"94898f747476e269b2910d42e769f2bbb6be0cb466ad92f9d381f55799d2756e","src/dx12/adapter.rs":"9923abf84344c9ec2719ce4a0829bbc9b78307721b485bfd65c2912062037fe5","src/dx12/command.rs":"4bbbfa0583d0670a4cdefe55ec0513e84ac955b2c06dc2ee59fcb89d1e63fad1","src/dx12/conv.rs":"ef5fa91bbe8b044b7f7949452a04eefbf4b0d3a97f6d89665e021efae8568643","src/dx12/dcomp.rs":"53bde57557d80e571257f76933d66475a765e063d8b635675f9dd2563039a4c5","src/dx12/descriptor.rs":"ccd4feb6bd3e0a0ffc26142f8a81fca26180d0f50146b6eb2f670cbc89ea7064","src/dx12/device.rs":"f797941a33c5d973dd79a7633ef65db9aafab1dcc12d53370050c5470858b943","src/dx12/instance.rs":"75bddc3807756c691ede3ff944915e443a8bb2b5ac6d0d99babd4ed50d1e3fb9","src/dx12/mod.rs":"6b49fdcdb0220a1297859916c55df647bc23a6891eacbc92874f0e1a0f806299","src/dx12/sampler.rs":"d18d243efe4fa667dbab5b75b5b91d47de94d441976d9f44a46a2b49ba38473d","src/dx12/shader_compilation.rs":"c901a797c69e08c8c0ec93ea37c5f31084eb21c26c7d703d7031f987f2243509","src/dx12/suballocation.rs":"014e9ec4a94519b877ad3adc2ea5d182aa6cdf502248009d28dc5833a9edb93c","src/dx12/types.rs":"3fc7619fc09303eb3c936d4ded6889f94ce9e8b9aa62742ce900baa1b1e1cca7","src/dx12/view.rs":"79b3f7331d9795e60f9b53023cbf0df46c3a05b1e8bd5c7bcca8acdd235b124f","src/dynamic/adapter.rs":"e93f7d082a3950c9e8ccff8a631d251c7598b4b25dda9fe6347dadfa3ba07829","src/dynamic/command.rs":"9635dea15d8a885011d2b8b6b9cc5ffe2126cc3f141f47f7aaf46e1f201abea9","src/dynamic/device.rs":"4c8368a5ba6947f982f16accef75e15cbef2dcb6e4bd5995783b7d6fdf131ff6","src/dynamic/instance.rs":"7b515c201e1ca24f24439544dbfa1d19ea1412a4f89bd803e009aed13b021e55","src/dynamic/mod.rs":"2577d3aef6441f5b42b427d80ba3cf7fee2a97b2fc12335a1fba383e8a79a9b2","src/dynamic/queue.rs":"d76abb4797e90253386d24584f186dbe1909e772560156b2e891fa043cfefbdc","src/dynamic/surface.rs":"4328c2fe86931f50aa00ac3d6982d0879b774eebf7a507903d1b1898c891fb4d","src/gles/adapter.rs":"7cbe1b3dda180d0eee69af3474308175dfb964db071ec9779baf21ffd641f679","src/gles/command.rs":"c13d50eeb1a4aaab367a3b4a7fe6c25c8c73377e68d0d8cc43791d1a7202d23b","src/gles/conv.rs":"de1ad6c07d26e8f9f3be8a7a51bca212e92fd5449aaa85c6ad9c37b91afa6994","src/gles/device.rs":"0ab205747f317d517204def9281cb3561241a53bb2233252adfb7581c015c1ba","src/gles/egl.rs":"2a336cd6bf3cc6660677ac2621f903c9dd72a1cf484d41c7b69c341b809844c4","src/gles/emscripten.rs":"316d2bb6f2a4bb126dbe68a223f7393399080d116b61c39504454acdf4f9cfaf","src/gles/fence.rs":"083cd49747aba6272002aba0b0c37e5768cdbc2a1b8bacd1a244ee905d3f7b0f","src/gles/mod.rs":"24a29ca8f7a5c3c7601d74b3fd8a9d4b402e7b794b6fd70bda36acf5960ae828","src/gles/queue.rs":"5152f5698a2998a55125d13f04788b960726fd4b49ae4d2ec8f9642c8825c7fd","src/gles/shaders/clear.frag":"9133ed8ed97d3641fbb6b5f5ea894a3554c629ccc1b80a5fc9221d7293aa1954","src/gles/shaders/clear.vert":"a543768725f4121ff2e9e1fb5b00644931e9d6f2f946c0ef01968afb5a135abd","src/gles/shaders/srgb_present.frag":"dd9a43c339a2fa4ccf7f6a1854c6f400cabf271a7d5e9230768e9f39d47f3ff5","src/gles/shaders/srgb_present.vert":"6e85d489403d80b81cc94790730bb53b309dfc5eeede8f1ea3412a660f31d357","src/gles/web.rs":"cb5940bf7b2381811675011b640040274f407a7d1908d0f82c813d6a9d3b00f7","src/gles/wgl.rs":"ed0cee8844447b461ed5340f81eb55bb051ceaac67a5768985318ceac133cbe4","src/lib.rs":"857e57ce6d1dc95f6b1aa05c30e52423ff488ed892b5ad1c010a14252633d436","src/metal/adapter.rs":"9184c7658efe5dd43224d23294ebd3fe98a19b0290c41703496de276dad5f996","src/metal/command.rs":"20bf613b67ccc043de6e8ad3f3d332bbb678cc06c1593cf1880083de090574ba","src/metal/conv.rs":"85e8168be334ba24d109575a0a7e91b2ad3459403173e99e5cdd5d977cc5c18f","src/metal/device.rs":"b4a7aba8b9bfc348cd127a242ac7254b661600982e2cede4c9286799311d4867","src/metal/layer_observer.rs":"8370a6e443d01739b951b8538ee719a03b69fc0cbac92c748db418fbcc8837b5","src/metal/mod.rs":"82d7e8b96ba04fab5b42722574e9f081def9e50c92dcc7d554d8111b9d0aa2a1","src/metal/surface.rs":"22dc6da86ac74b044b6498764920f0467bb5060f4dffb156b6c1e260db0c48b7","src/metal/time.rs":"c32d69f30e846dfcc0e39e01097fb80df63b2bebb6586143bb62494999850246","src/noop/buffer.rs":"b5edc5e2c52287dfbd4f619e36097ac233041eb9ab287b889b6ee477d740fa09","src/noop/command.rs":"3de99a1a260cfea2e6ca2e76797c1923cc26b069b08362c38798ce27cdc75543","src/noop/mod.rs":"85253d9c36fca50e14c562fb35928e69342bcd367a78d9c512d6ce15702c74a5","src/validation_canary.rs":"2e8f84e5f85671b3e55ddd410476171c762e34cbea315b37921cbb6ff18bfb4f","src/vulkan/adapter.rs":"0c973c328064c509e2c05cf7d72fff881aad3d75234aa6040f09869e986eec17","src/vulkan/command.rs":"22fd05428c141ce58000c8f3541d39195023ffdfb72c4b00379a5c50a3ecea82","src/vulkan/conv.rs":"b89788f8f89283a80ee99b2d4231c4fe2ad36906f8743f6e9e1eaa974edd4816","src/vulkan/device.rs":"3c319b40853fea9bd1f4a0ee9677caabea8c8bbfa267f09651ae0424735c0224","src/vulkan/drm.rs":"45f7bf1dd854688a65261e4674d80f90c997b193a162fd2ae658acf4e2003552","src/vulkan/instance.rs":"6740bc9ca240aa512509520d2b5a9cd2129330c413d94fce786b8301fa5f2202","src/vulkan/mod.rs":"ee5b76246621e4e5d78ead70f49c94b5e3d48b616f8524e669213b9adaed31bb","src/vulkan/sampler.rs":"f65729d6df5cce681b7756b3e48074017f0c7f42da69ca55e26cc723cd14ad59","src/vulkan/semaphore_list.rs":"102266d8e1b9f2ec1decf681bcc9e1a4cbff29533a258f2699fb6c573c434771"},"package":null} +\ No newline at end of file diff --git a/third_party/rust/wgpu-hal/Cargo.toml b/third_party/rust/wgpu-hal/Cargo.toml @@ -190,7 +190,7 @@ version = "0.16" optional = true [dependencies.hashbrown] -version = "0.15" +version = "0.16" features = [ "default-hasher", "inline-more", @@ -243,7 +243,7 @@ version = "0.11" default-features = false [dev-dependencies.glam] -version = "0.30" +version = "0.30.7" [dev-dependencies.naga] version = "26.0.0" @@ -347,7 +347,7 @@ version = "1" optional = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies.smallvec] -version = "1.13.1" +version = "1.14" features = ["union"] optional = true @@ -393,7 +393,7 @@ version = "0.2.5" optional = true [target."cfg(unix)".dependencies.libc] -version = "0.2.168" +version = "0.2.171" optional = true default-features = false diff --git a/third_party/rust/wgpu-hal/src/dx12/adapter.rs b/third_party/rust/wgpu-hal/src/dx12/adapter.rs @@ -528,6 +528,22 @@ impl super::Adapter { wgt::Features::SHADER_INT64_ATOMIC_ALL_OPS | wgt::Features::SHADER_INT64_ATOMIC_MIN_MAX, atomic_int64_on_typed_resource_supported, ); + let mesh_shader_supported = { + let mut features7 = Direct3D12::D3D12_FEATURE_DATA_D3D12_OPTIONS7::default(); + unsafe { + device.CheckFeatureSupport( + Direct3D12::D3D12_FEATURE_D3D12_OPTIONS7, + <*mut _>::cast(&mut features7), + size_of_val(&features7) as u32, + ) + } + .is_ok() + && features7.MeshShaderTier != Direct3D12::D3D12_MESH_SHADER_TIER_NOT_SUPPORTED + }; + features.set( + wgt::Features::EXPERIMENTAL_MESH_SHADER, + mesh_shader_supported, + ); // TODO: Determine if IPresentationManager is supported let presentation_timer = auxil::dxgi::time::PresentationTimer::new_dxgi(); @@ -648,10 +664,15 @@ impl super::Adapter { max_buffer_size: i32::MAX as u64, max_non_sampler_bindings: 1_000_000, - max_task_workgroup_total_count: 0, - max_task_workgroups_per_dimension: 0, + // Source: https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-api + max_task_workgroup_total_count: 2u32.pow(22), + // Technically it says "64k" but I highly doubt they want 65536 for compute and exactly 64,000 for task workgroups + max_task_workgroups_per_dimension: + Direct3D12::D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + // Multiview not supported by WGPU yet max_mesh_multiview_count: 0, - max_mesh_output_layers: 0, + // This seems to be right, and I can't find anything to suggest it would be less than the 2048 provided here + max_mesh_output_layers: Direct3D12::D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION, max_blas_primitive_count: if supports_ray_tracing { 1 << 29 // 2^29 diff --git a/third_party/rust/wgpu-hal/src/dx12/command.rs b/third_party/rust/wgpu-hal/src/dx12/command.rs @@ -1121,8 +1121,8 @@ impl crate::CommandEncoder for super::CommandEncoder { .enumerate() { if let Some(stride) = stride { - if vb.StrideInBytes != stride.get() { - vb.StrideInBytes = stride.get(); + if vb.StrideInBytes != stride { + vb.StrideInBytes = stride; self.pass.dirty_vertex_buffers |= 1 << index; } } @@ -1228,11 +1228,16 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks( &mut self, - _group_count_x: u32, - _group_count_y: u32, - _group_count_z: u32, + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, ) { - unreachable!() + self.prepare_dispatch([group_count_x, group_count_y, group_count_z]); + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + unsafe { + cmd_list6.DispatchMesh(group_count_x, group_count_y, group_count_z); + } } unsafe fn draw_indirect( &mut self, @@ -1314,11 +1319,36 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks_indirect( &mut self, - _buffer: &<Self::A as crate::Api>::Buffer, - _offset: wgt::BufferAddress, - _draw_count: u32, + buffer: &<Self::A as crate::Api>::Buffer, + offset: wgt::BufferAddress, + draw_count: u32, ) { - unreachable!() + if self + .pass + .layout + .special_constants + .as_ref() + .and_then(|sc| sc.indirect_cmd_signatures.as_ref()) + .is_some() + { + self.update_root_elements(); + } else { + self.prepare_dispatch([0; 3]); + } + + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + let cmd_signature = &self + .pass + .layout + .special_constants + .as_ref() + .and_then(|sc| sc.indirect_cmd_signatures.as_ref()) + .unwrap_or_else(|| &self.shared.cmd_signatures) + .draw_mesh; + unsafe { + cmd_list6.ExecuteIndirect(cmd_signature, draw_count, &buffer.resource, offset, None, 0); + } } unsafe fn draw_indirect_count( &mut self, @@ -1362,13 +1392,25 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks_indirect_count( &mut self, - _buffer: &<Self::A as crate::Api>::Buffer, - _offset: wgt::BufferAddress, - _count_buffer: &<Self::A as crate::Api>::Buffer, - _count_offset: wgt::BufferAddress, - _max_count: u32, + buffer: &<Self::A as crate::Api>::Buffer, + offset: wgt::BufferAddress, + count_buffer: &<Self::A as crate::Api>::Buffer, + count_offset: wgt::BufferAddress, + max_count: u32, ) { - unreachable!() + self.prepare_dispatch([0; 3]); + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + unsafe { + cmd_list6.ExecuteIndirect( + &self.shared.cmd_signatures.draw_mesh, + max_count, + &buffer.resource, + offset, + &count_buffer.resource, + count_offset, + ); + } } // compute diff --git a/third_party/rust/wgpu-hal/src/dx12/device.rs b/third_party/rust/wgpu-hal/src/dx12/device.rs @@ -140,6 +140,16 @@ impl super::Device { }], 0, )?, + draw_mesh: Self::create_command_signature( + &raw, + None, + size_of::<wgt::DispatchIndirectArgs>(), + &[Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + ..Default::default() + }], + 0, + )?, dispatch: Self::create_command_signature( &raw, None, @@ -185,10 +195,7 @@ impl super::Device { Ok(super::Device { raw: raw.clone(), present_queue, - idler: super::Idler { - fence: idle_fence, - event: Event::create(false, false)?, - }, + idler: super::Idler { fence: idle_fence }, features, shared: Arc::new(shared), rtv_pool: Arc::new(Mutex::new(rtv_pool)), @@ -246,16 +253,14 @@ impl super::Device { return Err(crate::DeviceError::Lost); } + let event = Event::create(false, false)?; + let value = cur_value + 1; unsafe { self.present_queue.Signal(&self.idler.fence, value) } .into_device_result("Signal")?; - let hr = unsafe { - self.idler - .fence - .SetEventOnCompletion(value, self.idler.event.0) - }; + let hr = unsafe { self.idler.fence.SetEventOnCompletion(value, event.0) }; hr.into_device_result("Set event")?; - unsafe { Threading::WaitForSingleObject(self.idler.event.0, Threading::INFINITE) }; + unsafe { Threading::WaitForSingleObject(event.0, Threading::INFINITE) }; Ok(()) } @@ -1394,6 +1399,19 @@ impl crate::Device for super::Device { ], 0, )?, + draw_mesh: Self::create_command_signature( + &self.raw, + Some(&raw), + special_constant_buffer_args_len + size_of::<wgt::DispatchIndirectArgs>(), + &[ + constant_indirect_argument_desc, + Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + ..Default::default() + }, + ], + 0, + )?, dispatch: Self::create_command_signature( &self.raw, Some(&raw), @@ -1825,60 +1843,10 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result<super::RenderPipeline, crate::PipelineError> { + let mut shader_stages = wgt::ShaderStages::empty(); + let root_signature = + unsafe { borrow_optional_interface_temporarily(&desc.layout.shared.signature) }; let (topology_class, topology) = conv::map_topology(desc.primitive.topology); - let mut shader_stages = wgt::ShaderStages::VERTEX; - - let (vertex_stage_desc, vertex_buffers_desc) = match &desc.vertex_processor { - crate::VertexProcessor::Standard { - vertex_buffers, - vertex_stage, - } => (vertex_stage, *vertex_buffers), - crate::VertexProcessor::Mesh { .. } => unreachable!(), - }; - - let blob_vs = self.load_shader( - vertex_stage_desc, - desc.layout, - naga::ShaderStage::Vertex, - desc.fragment_stage.as_ref(), - )?; - let blob_fs = match desc.fragment_stage { - Some(ref stage) => { - shader_stages |= wgt::ShaderStages::FRAGMENT; - Some(self.load_shader(stage, desc.layout, naga::ShaderStage::Fragment, None)?) - } - None => None, - }; - - let mut vertex_strides = [None; crate::MAX_VERTEX_BUFFERS]; - let mut input_element_descs = Vec::new(); - for (i, (stride, vbuf)) in vertex_strides - .iter_mut() - .zip(vertex_buffers_desc) - .enumerate() - { - *stride = NonZeroU32::new(vbuf.array_stride as u32); - let (slot_class, step_rate) = match vbuf.step_mode { - wgt::VertexStepMode::Vertex => { - (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0) - } - wgt::VertexStepMode::Instance => { - (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1) - } - }; - for attribute in vbuf.attributes { - input_element_descs.push(Direct3D12::D3D12_INPUT_ELEMENT_DESC { - SemanticName: windows::core::PCSTR(NAGA_LOCATION_SEMANTIC.as_ptr()), - SemanticIndex: attribute.shader_location, - Format: auxil::dxgi::conv::map_vertex_format(attribute.format), - InputSlot: i as u32, - AlignedByteOffset: attribute.offset as u32, - InputSlotClass: slot_class, - InstanceDataStepRate: step_rate, - }); - } - } - let mut rtv_formats = [Dxgi::Common::DXGI_FORMAT_UNKNOWN; Direct3D12::D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT as usize]; for (rtv_format, ct) in rtv_formats.iter_mut().zip(desc.color_targets) { @@ -1893,7 +1861,7 @@ impl crate::Device for super::Device { .map(|ds| ds.bias) .unwrap_or_default(); - let raw_rasterizer = Direct3D12::D3D12_RASTERIZER_DESC { + let rasterizer_state = Direct3D12::D3D12_RASTERIZER_DESC { FillMode: conv::map_polygon_mode(desc.primitive.polygon_mode), CullMode: match desc.primitive.cull_mode { None => Direct3D12::D3D12_CULL_MODE_NONE, @@ -1917,80 +1885,193 @@ impl crate::Device for super::Device { Direct3D12::D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF }, }; + let blob_fs = match desc.fragment_stage { + Some(ref stage) => { + shader_stages |= wgt::ShaderStages::FRAGMENT; + Some(self.load_shader(stage, desc.layout, naga::ShaderStage::Fragment, None)?) + } + None => None, + }; + let pixel_shader = match &blob_fs { + Some(shader) => shader.create_native_shader(), + None => Direct3D12::D3D12_SHADER_BYTECODE::default(), + }; + let mut vertex_strides = [None; crate::MAX_VERTEX_BUFFERS]; + let stream_output = Direct3D12::D3D12_STREAM_OUTPUT_DESC { + pSODeclaration: ptr::null(), + NumEntries: 0, + pBufferStrides: ptr::null(), + NumStrides: 0, + RasterizedStream: 0, + }; + let blend_state = Direct3D12::D3D12_BLEND_DESC { + AlphaToCoverageEnable: Foundation::BOOL::from( + desc.multisample.alpha_to_coverage_enabled, + ), + IndependentBlendEnable: true.into(), + RenderTarget: conv::map_render_targets(desc.color_targets), + }; + let depth_stencil_state = match desc.depth_stencil { + Some(ref ds) => conv::map_depth_stencil(ds), + None => Default::default(), + }; + let dsv_format = desc + .depth_stencil + .as_ref() + .map_or(Dxgi::Common::DXGI_FORMAT_UNKNOWN, |ds| { + auxil::dxgi::conv::map_texture_format(ds.format) + }); + let sample_desc = Dxgi::Common::DXGI_SAMPLE_DESC { + Count: desc.multisample.count, + Quality: 0, + }; + let cached_pso = Direct3D12::D3D12_CACHED_PIPELINE_STATE { + pCachedBlob: ptr::null(), + CachedBlobSizeInBytes: 0, + }; + let flags = Direct3D12::D3D12_PIPELINE_STATE_FLAG_NONE; - let raw_desc = Direct3D12::D3D12_GRAPHICS_PIPELINE_STATE_DESC { - pRootSignature: unsafe { - borrow_optional_interface_temporarily(&desc.layout.shared.signature) - }, - VS: blob_vs.create_native_shader(), - PS: match &blob_fs { - Some(shader) => shader.create_native_shader(), - None => Direct3D12::D3D12_SHADER_BYTECODE::default(), - }, - GS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - DS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - HS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - StreamOutput: Direct3D12::D3D12_STREAM_OUTPUT_DESC { - pSODeclaration: ptr::null(), - NumEntries: 0, - pBufferStrides: ptr::null(), - NumStrides: 0, - RasterizedStream: 0, - }, - BlendState: Direct3D12::D3D12_BLEND_DESC { - AlphaToCoverageEnable: Foundation::BOOL::from( - desc.multisample.alpha_to_coverage_enabled, - ), - IndependentBlendEnable: true.into(), - RenderTarget: conv::map_render_targets(desc.color_targets), - }, - SampleMask: desc.multisample.mask as u32, - RasterizerState: raw_rasterizer, - DepthStencilState: match desc.depth_stencil { - Some(ref ds) => conv::map_depth_stencil(ds), - None => Default::default(), - }, - InputLayout: Direct3D12::D3D12_INPUT_LAYOUT_DESC { - pInputElementDescs: if input_element_descs.is_empty() { - ptr::null() - } else { - input_element_descs.as_ptr() - }, - NumElements: input_element_descs.len() as u32, - }, - IBStripCutValue: match desc.primitive.strip_index_format { - Some(wgt::IndexFormat::Uint16) => { - Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF + let raw: Direct3D12::ID3D12PipelineState = match &desc.vertex_processor { + &crate::VertexProcessor::Standard { + vertex_buffers, + ref vertex_stage, + } => { + shader_stages |= wgt::ShaderStages::VERTEX; + let blob_vs = self.load_shader( + vertex_stage, + desc.layout, + naga::ShaderStage::Vertex, + desc.fragment_stage.as_ref(), + )?; + + let mut input_element_descs = Vec::new(); + for (i, (stride, vbuf)) in vertex_strides.iter_mut().zip(vertex_buffers).enumerate() + { + *stride = Some(vbuf.array_stride as u32); + let (slot_class, step_rate) = match vbuf.step_mode { + wgt::VertexStepMode::Vertex => { + (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0) + } + wgt::VertexStepMode::Instance => { + (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1) + } + }; + for attribute in vbuf.attributes { + input_element_descs.push(Direct3D12::D3D12_INPUT_ELEMENT_DESC { + SemanticName: windows::core::PCSTR(NAGA_LOCATION_SEMANTIC.as_ptr()), + SemanticIndex: attribute.shader_location, + Format: auxil::dxgi::conv::map_vertex_format(attribute.format), + InputSlot: i as u32, + AlignedByteOffset: attribute.offset as u32, + InputSlotClass: slot_class, + InstanceDataStepRate: step_rate, + }); + } + } + let raw_desc = Direct3D12::D3D12_GRAPHICS_PIPELINE_STATE_DESC { + pRootSignature: root_signature, + VS: blob_vs.create_native_shader(), + PS: pixel_shader, + GS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + DS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + HS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + StreamOutput: stream_output, + BlendState: blend_state, + SampleMask: desc.multisample.mask as u32, + RasterizerState: rasterizer_state, + DepthStencilState: depth_stencil_state, + InputLayout: Direct3D12::D3D12_INPUT_LAYOUT_DESC { + pInputElementDescs: if input_element_descs.is_empty() { + ptr::null() + } else { + input_element_descs.as_ptr() + }, + NumElements: input_element_descs.len() as u32, + }, + IBStripCutValue: match desc.primitive.strip_index_format { + Some(wgt::IndexFormat::Uint16) => { + Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF + } + Some(wgt::IndexFormat::Uint32) => { + Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF + } + None => Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, + }, + PrimitiveTopologyType: topology_class, + NumRenderTargets: desc.color_targets.len() as u32, + RTVFormats: rtv_formats, + DSVFormat: dsv_format, + SampleDesc: sample_desc, + NodeMask: 0, + CachedPSO: cached_pso, + Flags: flags, + }; + unsafe { + profiling::scope!("ID3D12Device::CreateGraphicsPipelineState"); + self.raw.CreateGraphicsPipelineState(&raw_desc) } - Some(wgt::IndexFormat::Uint32) => { - Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF + } + crate::VertexProcessor::Mesh { + task_stage, + mesh_stage, + } => { + let blob_ts = if let Some(ts) = task_stage { + shader_stages |= wgt::ShaderStages::TASK; + Some(self.load_shader( + ts, + desc.layout, + naga::ShaderStage::Task, + desc.fragment_stage.as_ref(), + )?) + } else { + None + }; + let task_shader = if let Some(ts) = &blob_ts { + ts.create_native_shader() + } else { + Default::default() + }; + shader_stages |= wgt::ShaderStages::MESH; + let blob_ms = self.load_shader( + mesh_stage, + desc.layout, + naga::ShaderStage::Mesh, + desc.fragment_stage.as_ref(), + )?; + let desc = super::MeshShaderPipelineStateStream { + root_signature: root_signature + .as_ref() + .map(|a| a.as_raw().cast()) + .unwrap_or(ptr::null_mut()), + task_shader, + pixel_shader, + mesh_shader: blob_ms.create_native_shader(), + blend_state, + sample_mask: desc.multisample.mask as u32, + rasterizer_state, + depth_stencil_state, + primitive_topology_type: topology_class, + rtv_formats: Direct3D12::D3D12_RT_FORMAT_ARRAY { + RTFormats: rtv_formats, + NumRenderTargets: desc.color_targets.len() as u32, + }, + dsv_format, + sample_desc, + node_mask: 0, + cached_pso, + flags, + }; + let mut raw_desc = unsafe { desc.to_bytes() }; + let stream_desc = Direct3D12::D3D12_PIPELINE_STATE_STREAM_DESC { + SizeInBytes: raw_desc.len(), + pPipelineStateSubobjectStream: raw_desc.as_mut_ptr().cast(), + }; + let device: Direct3D12::ID3D12Device2 = self.raw.cast().unwrap(); + unsafe { + profiling::scope!("ID3D12Device2::CreatePipelineState"); + device.CreatePipelineState(&stream_desc) } - None => Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, - }, - PrimitiveTopologyType: topology_class, - NumRenderTargets: desc.color_targets.len() as u32, - RTVFormats: rtv_formats, - DSVFormat: desc - .depth_stencil - .as_ref() - .map_or(Dxgi::Common::DXGI_FORMAT_UNKNOWN, |ds| { - auxil::dxgi::conv::map_texture_format(ds.format) - }), - SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC { - Count: desc.multisample.count, - Quality: 0, - }, - NodeMask: 0, - CachedPSO: Direct3D12::D3D12_CACHED_PIPELINE_STATE { - pCachedBlob: ptr::null(), - CachedBlobSizeInBytes: 0, - }, - Flags: Direct3D12::D3D12_PIPELINE_STATE_FLAG_NONE, - }; - - let raw: Direct3D12::ID3D12PipelineState = { - profiling::scope!("ID3D12Device::CreateGraphicsPipelineState"); - unsafe { self.raw.CreateGraphicsPipelineState(&raw_desc) } + } } .map_err(|err| crate::PipelineError::Linkage(shader_stages, err.to_string()))?; @@ -2166,7 +2247,9 @@ impl crate::Device for super::Device { return Ok(true); } - unsafe { fence.raw.SetEventOnCompletion(value, self.idler.event.0) } + let event = Event::create(false, false)?; + + unsafe { fence.raw.SetEventOnCompletion(value, event.0) } .into_device_result("Set event")?; let start_time = Instant::now(); @@ -2202,7 +2285,7 @@ impl crate::Device for super::Device { match unsafe { Threading::WaitForSingleObject( - self.idler.event.0, + event.0, remaining_wait_duration.as_millis().try_into().unwrap(), ) } { diff --git a/third_party/rust/wgpu-hal/src/dx12/mod.rs b/third_party/rust/wgpu-hal/src/dx12/mod.rs @@ -86,7 +86,7 @@ mod types; mod view; use alloc::{borrow::ToOwned as _, string::String, sync::Arc, vec::Vec}; -use core::{ffi, fmt, mem, num::NonZeroU32, ops::Deref}; +use core::{ffi, fmt, mem, ops::Deref}; use arrayvec::ArrayVec; use hashbrown::HashMap; @@ -653,13 +653,13 @@ impl Drop for Event { /// Helper structure for waiting for GPU. struct Idler { fence: Direct3D12::ID3D12Fence, - event: Event, } #[derive(Debug, Clone)] struct CommandSignatures { draw: Direct3D12::ID3D12CommandSignature, draw_indexed: Direct3D12::ID3D12CommandSignature, + draw_mesh: Direct3D12::ID3D12CommandSignature, dispatch: Direct3D12::ID3D12CommandSignature, } @@ -1168,7 +1168,7 @@ pub struct RenderPipeline { raw: Direct3D12::ID3D12PipelineState, layout: PipelineLayoutShared, topology: Direct3D::D3D_PRIMITIVE_TOPOLOGY, - vertex_strides: [Option<NonZeroU32>; crate::MAX_VERTEX_BUFFERS], + vertex_strides: [Option<u32>; crate::MAX_VERTEX_BUFFERS], } impl crate::DynRenderPipeline for RenderPipeline {} @@ -1600,3 +1600,116 @@ pub enum ShaderModuleSource { DxilPassthrough(DxilPassthroughShader), HlslPassthrough(HlslPassthroughShader), } + +#[repr(C)] +#[derive(Debug)] +struct MeshShaderPipelineStateStream { + root_signature: *mut Direct3D12::ID3D12RootSignature, + task_shader: Direct3D12::D3D12_SHADER_BYTECODE, + mesh_shader: Direct3D12::D3D12_SHADER_BYTECODE, + pixel_shader: Direct3D12::D3D12_SHADER_BYTECODE, + blend_state: Direct3D12::D3D12_BLEND_DESC, + sample_mask: u32, + rasterizer_state: Direct3D12::D3D12_RASTERIZER_DESC, + depth_stencil_state: Direct3D12::D3D12_DEPTH_STENCIL_DESC, + primitive_topology_type: Direct3D12::D3D12_PRIMITIVE_TOPOLOGY_TYPE, + rtv_formats: Direct3D12::D3D12_RT_FORMAT_ARRAY, + dsv_format: Dxgi::Common::DXGI_FORMAT, + sample_desc: Dxgi::Common::DXGI_SAMPLE_DESC, + node_mask: u32, + cached_pso: Direct3D12::D3D12_CACHED_PIPELINE_STATE, + flags: Direct3D12::D3D12_PIPELINE_STATE_FLAGS, +} +impl MeshShaderPipelineStateStream { + /// # Safety + /// + /// Returned bytes contain pointers into this struct, for them to be valid, + /// this struct may be at the same location. As if `as_bytes<'a>(&'a self) -> Vec<u8> + 'a` + pub unsafe fn to_bytes(&self) -> Vec<u8> { + use Direct3D12::*; + let mut bytes = Vec::new(); + + macro_rules! push_subobject { + ($subobject_type:expr, $data:expr) => {{ + // Ensure 8-byte alignment for the subobject start + let alignment = 8; + let aligned_length = bytes.len().next_multiple_of(alignment); + bytes.resize(aligned_length, 0); + + // Append the type tag (u32) + let tag: u32 = $subobject_type.0 as u32; + bytes.extend_from_slice(&tag.to_ne_bytes()); + + // Align the data + let obj_align = align_of_val(&$data); + let data_start = bytes.len().next_multiple_of(obj_align); + bytes.resize(data_start, 0); + + // Append the data itself + #[allow(clippy::ptr_as_ptr, trivial_casts)] + let data_ptr = &$data as *const _ as *const u8; + let data_size = size_of_val(&$data); + let slice = unsafe { core::slice::from_raw_parts(data_ptr, data_size) }; + bytes.extend_from_slice(slice); + }}; + } + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE, + self.root_signature + ); + if !self.task_shader.pShaderBytecode.is_null() { + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS, self.task_shader); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS, self.mesh_shader); + if !self.pixel_shader.pShaderBytecode.is_null() { + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS, self.pixel_shader); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, self.blend_state); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, + self.sample_mask + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, + self.rasterizer_state + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, + self.depth_stencil_state + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY, + self.primitive_topology_type + ); + if self.rtv_formats.NumRenderTargets != 0 { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS, + self.rtv_formats + ); + } + if self.dsv_format != Dxgi::Common::DXGI_FORMAT_UNKNOWN { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT, + self.dsv_format + ); + } + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, + self.sample_desc + ); + if self.node_mask != 0 { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK, + self.node_mask + ); + } + if !self.cached_pso.pCachedBlob.is_null() { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO, + self.cached_pso + ); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS, self.flags); + bytes + } +} diff --git a/third_party/rust/wgpu-hal/src/metal/device.rs b/third_party/rust/wgpu-hal/src/metal/device.rs @@ -1154,7 +1154,15 @@ impl crate::Device for super::Device { .try_into() .unwrap() }, - indexed_by_vertex: (vbl.step_mode == wgt::VertexStepMode::Vertex {}), + step_mode: match (vbl.array_stride == 0, vbl.step_mode) { + (true, _) => naga::back::msl::VertexBufferStepMode::Constant, + (false, wgt::VertexStepMode::Vertex) => { + naga::back::msl::VertexBufferStepMode::ByVertex + } + (false, wgt::VertexStepMode::Instance) => { + naga::back::msl::VertexBufferStepMode::ByInstance + } + }, attributes, }); } diff --git a/third_party/rust/wgpu-hal/src/vulkan/adapter.rs b/third_party/rust/wgpu-hal/src/vulkan/adapter.rs @@ -129,6 +129,10 @@ pub struct PhysicalDeviceFeatures { } impl PhysicalDeviceFeatures { + pub fn get_core(&self) -> vk::PhysicalDeviceFeatures { + self.core + } + /// Add the members of `self` into `info.enabled_features` and its `p_next` chain. pub fn add_to_device_create<'a>( &'a mut self, @@ -1859,6 +1863,10 @@ impl super::Adapter { self.raw } + pub fn get_physical_device_features(&self) -> &PhysicalDeviceFeatures { + &self.phd_features + } + pub fn physical_device_capabilities(&self) -> &PhysicalDeviceProperties { &self.phd_capabilities } @@ -2166,6 +2174,7 @@ impl super::Adapter { force_loop_bounding: true, use_storage_input_output_16: features.contains(wgt::Features::SHADER_F16) && self.phd_features.supports_storage_input_output_16(), + fake_missing_bindings: false, // We need to build this separately for each invocation, so just default it out here binding_map: BTreeMap::default(), debug_info: None, diff --git a/third_party/rust/wgpu-hal/src/vulkan/conv.rs b/third_party/rust/wgpu-hal/src/vulkan/conv.rs @@ -161,7 +161,8 @@ impl super::PrivateCapabilities { pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option<wgt::TextureFormat> { use ash::vk::Format as F; use wgt::TextureFormat as Tf; - // List we care about pulled from https://vulkan.gpuinfo.org/listsurfaceformats.php + // List we care about pulled from https://vulkan.gpuinfo.org/listsurfaceformats.php. + // Device::create_swapchain() hardcodes linear scRGB for fp16, non-linear sRGB otherwise. Some(match sf.color_space { vk::ColorSpaceKHR::SRGB_NONLINEAR => match sf.format { F::B8G8R8A8_UNORM => Tf::Bgra8Unorm, @@ -169,13 +170,13 @@ pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option<wgt::TextureFo F::R8G8B8A8_SNORM => Tf::Rgba8Snorm, F::R8G8B8A8_UNORM => Tf::Rgba8Unorm, F::R8G8B8A8_SRGB => Tf::Rgba8UnormSrgb, + F::R16G16B16A16_SNORM => Tf::Rgba16Snorm, + F::R16G16B16A16_UNORM => Tf::Rgba16Unorm, + F::A2B10G10R10_UNORM_PACK32 => Tf::Rgb10a2Unorm, _ => return None, }, vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT => match sf.format { F::R16G16B16A16_SFLOAT => Tf::Rgba16Float, - F::R16G16B16A16_SNORM => Tf::Rgba16Snorm, - F::R16G16B16A16_UNORM => Tf::Rgba16Unorm, - F::A2B10G10R10_UNORM_PACK32 => Tf::Rgb10a2Unorm, _ => return None, }, _ => return None, diff --git a/third_party/rust/wgpu-hal/src/vulkan/device.rs b/third_party/rust/wgpu-hal/src/vulkan/device.rs @@ -1480,20 +1480,55 @@ impl crate::Device for super::Device { &self, desc: &crate::BindGroupLayoutDescriptor, ) -> Result<super::BindGroupLayout, crate::DeviceError> { + // Iterate through the entries and accumulate our Vulkan + // DescriptorSetLayoutBindings and DescriptorBindingFlags, as well as + // our binding map and our descriptor counts. + // Note: not bothering with on stack arrays here as it's low frequency + let mut vk_bindings = Vec::new(); + let mut binding_flags = Vec::new(); + let mut binding_map = Vec::new(); + let mut next_binding = 0; + let mut contains_binding_arrays = false; let mut desc_count = gpu_descriptor::DescriptorTotalCount::default(); - let mut types = Vec::new(); for entry in desc.entries { + if entry.count.is_some() { + contains_binding_arrays = true; + } + + let partially_bound = desc + .flags + .contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND); + let mut flags = vk::DescriptorBindingFlags::empty(); + if partially_bound && entry.count.is_some() { + flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND; + } + if entry.count.is_some() { + flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND; + } + let count = entry.count.map_or(1, |c| c.get()); - if entry.binding as usize >= types.len() { - types.resize( - entry.binding as usize + 1, - (vk::DescriptorType::INPUT_ATTACHMENT, 0), - ); + match entry.ty { + wgt::BindingType::ExternalTexture => unimplemented!(), + _ => { + vk_bindings.push(vk::DescriptorSetLayoutBinding { + binding: next_binding, + descriptor_type: conv::map_binding_type(entry.ty), + descriptor_count: count, + stage_flags: conv::map_shader_stage(entry.visibility), + p_immutable_samplers: ptr::null(), + _marker: Default::default(), + }); + binding_flags.push(flags); + binding_map.push(( + entry.binding, + super::BindingInfo { + binding: next_binding, + binding_array_size: entry.count, + }, + )); + next_binding += 1; + } } - types[entry.binding as usize] = ( - conv::map_binding_type(entry.ty), - entry.count.map_or(1, |c| c.get()), - ); match entry.ty { wgt::BindingType::Buffer { @@ -1532,59 +1567,16 @@ impl crate::Device for super::Device { } } - //Note: not bothering with on stack array here as it's low frequency - let vk_bindings = desc - .entries - .iter() - .map(|entry| vk::DescriptorSetLayoutBinding { - binding: entry.binding, - descriptor_type: types[entry.binding as usize].0, - descriptor_count: types[entry.binding as usize].1, - stage_flags: conv::map_shader_stage(entry.visibility), - p_immutable_samplers: ptr::null(), - _marker: Default::default(), - }) - .collect::<Vec<_>>(); - - let binding_arrays: Vec<_> = desc - .entries - .iter() - .enumerate() - .filter_map(|(idx, entry)| entry.count.map(|count| (idx as u32, count))) - .collect(); - let vk_info = vk::DescriptorSetLayoutCreateInfo::default() .bindings(&vk_bindings) - .flags(if !binding_arrays.is_empty() { + .flags(if contains_binding_arrays { vk::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND_POOL } else { vk::DescriptorSetLayoutCreateFlags::empty() }); - let partially_bound = desc - .flags - .contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND); - - let binding_flag_vec = desc - .entries - .iter() - .map(|entry| { - let mut flags = vk::DescriptorBindingFlags::empty(); - - if partially_bound && entry.count.is_some() { - flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND; - } - - if entry.count.is_some() { - flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND; - } - - flags - }) - .collect::<Vec<_>>(); - - let mut binding_flag_info = vk::DescriptorSetLayoutBindingFlagsCreateInfo::default() - .binding_flags(&binding_flag_vec); + let mut binding_flag_info = + vk::DescriptorSetLayoutBindingFlagsCreateInfo::default().binding_flags(&binding_flags); let vk_info = vk_info.push_next(&mut binding_flag_info); @@ -1604,8 +1596,9 @@ impl crate::Device for super::Device { Ok(super::BindGroupLayout { raw, desc_count, - types: types.into_boxed_slice(), - binding_arrays, + entries: desc.entries.into(), + binding_map, + contains_binding_arrays, }) } unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) { @@ -1657,27 +1650,25 @@ impl crate::Device for super::Device { unsafe { self.shared.set_object_name(raw, label) }; } - let mut binding_arrays = BTreeMap::new(); + let mut binding_map = BTreeMap::new(); for (group, &layout) in desc.bind_group_layouts.iter().enumerate() { - for &(binding, binding_array_size) in &layout.binding_arrays { - binding_arrays.insert( + for &(binding, binding_info) in &layout.binding_map { + binding_map.insert( naga::ResourceBinding { group: group as u32, binding, }, naga::back::spv::BindingInfo { - binding_array_size: Some(binding_array_size.get()), + descriptor_set: group as u32, + binding: binding_info.binding, + binding_array_size: binding_info.binding_array_size.map(NonZeroU32::get), }, ); } } self.counters.pipeline_layouts.add(1); - - Ok(super::PipelineLayout { - raw, - binding_arrays, - }) + Ok(super::PipelineLayout { raw, binding_map }) } unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) { unsafe { @@ -1699,9 +1690,7 @@ impl crate::Device for super::Device { super::AccelerationStructure, >, ) -> Result<super::BindGroup, crate::DeviceError> { - let contains_binding_arrays = !desc.layout.binding_arrays.is_empty(); - - let desc_set_layout_flags = if contains_binding_arrays { + let desc_set_layout_flags = if desc.layout.contains_binding_arrays { gpu_descriptor::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND } else { gpu_descriptor::DescriptorSetLayoutCreateFlags::empty() @@ -1787,18 +1776,22 @@ impl crate::Device for super::Device { Vec::with_capacity(desc.acceleration_structures.len()); let mut raw_acceleration_structures = ExtendStack::from_vec_capacity(&mut raw_acceleration_structures); - for entry in desc.entries { - let (ty, size) = desc.layout.types[entry.binding as usize]; - if size == 0 { - continue; // empty slot - } - let mut write = vk::WriteDescriptorSet::default() - .dst_set(*set.raw()) - .dst_binding(entry.binding) - .descriptor_type(ty); - write = match ty { - vk::DescriptorType::SAMPLER => { + let layout_and_entry_iter = desc.entries.iter().map(|entry| { + let layout = desc + .layout + .entries + .iter() + .find(|layout_entry| layout_entry.binding == entry.binding) + .expect("internal error: no layout entry found with binding slot"); + (layout, entry) + }); + let mut next_binding = 0; + for (layout, entry) in layout_and_entry_iter { + let write = vk::WriteDescriptorSet::default().dst_set(*set.raw()); + + match layout.ty { + wgt::BindingType::Sampler(_) => { let start = entry.resource_index; let end = start + entry.count; let local_image_infos; @@ -1806,9 +1799,15 @@ impl crate::Device for super::Device { image_infos.extend(desc.samplers[start as usize..end as usize].iter().map( |sampler| vk::DescriptorImageInfo::default().sampler(sampler.raw), )); - write.image_info(local_image_infos) + writes.push( + write + .dst_binding(next_binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .image_info(local_image_infos), + ); + next_binding += 1; } - vk::DescriptorType::SAMPLED_IMAGE | vk::DescriptorType::STORAGE_IMAGE => { + wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => { let start = entry.resource_index; let end = start + entry.count; let local_image_infos; @@ -1822,12 +1821,15 @@ impl crate::Device for super::Device { .image_layout(layout) }, )); - write.image_info(local_image_infos) + writes.push( + write + .dst_binding(next_binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .image_info(local_image_infos), + ); + next_binding += 1; } - vk::DescriptorType::UNIFORM_BUFFER - | vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC - | vk::DescriptorType::STORAGE_BUFFER - | vk::DescriptorType::STORAGE_BUFFER_DYNAMIC => { + wgt::BindingType::Buffer { .. } => { let start = entry.resource_index; let end = start + entry.count; let local_buffer_infos; @@ -1842,9 +1844,15 @@ impl crate::Device for super::Device { ) }, )); - write.buffer_info(local_buffer_infos) + writes.push( + write + .dst_binding(next_binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .buffer_info(local_buffer_infos), + ); + next_binding += 1; } - vk::DescriptorType::ACCELERATION_STRUCTURE_KHR => { + wgt::BindingType::AccelerationStructure { .. } => { let start = entry.resource_index; let end = start + entry.count; @@ -1867,14 +1875,17 @@ impl crate::Device for super::Device { .acceleration_structures(local_raw_acceleration_structures), ); - write - .descriptor_count(entry.count) - .push_next(local_acceleration_structure_infos) + writes.push( + write + .dst_binding(next_binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .descriptor_count(entry.count) + .push_next(local_acceleration_structure_infos), + ); + next_binding += 1; } - _ => unreachable!(), - }; - - writes.push(write); + wgt::BindingType::ExternalTexture => unimplemented!(), + } } unsafe { self.shared.raw.update_descriptor_sets(&writes, &[]) }; @@ -2033,7 +2044,7 @@ impl crate::Device for super::Device { compiled_vs = Some(self.compile_stage( vertex_stage, naga::ShaderStage::Vertex, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_vs.as_ref().unwrap().create_info); } @@ -2045,14 +2056,14 @@ impl crate::Device for super::Device { compiled_ts = Some(self.compile_stage( t, naga::ShaderStage::Task, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_ts.as_ref().unwrap().create_info); } compiled_ms = Some(self.compile_stage( mesh_stage, naga::ShaderStage::Mesh, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_ms.as_ref().unwrap().create_info); } @@ -2062,7 +2073,7 @@ impl crate::Device for super::Device { let compiled = self.compile_stage( stage, naga::ShaderStage::Fragment, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?; stages.push(compiled.create_info); Some(compiled) @@ -2270,7 +2281,7 @@ impl crate::Device for super::Device { let compiled = self.compile_stage( &desc.stage, naga::ShaderStage::Compute, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?; let vk_infos = [{ diff --git a/third_party/rust/wgpu-hal/src/vulkan/mod.rs b/third_party/rust/wgpu-hal/src/vulkan/mod.rs @@ -462,6 +462,10 @@ pub struct Surface { } impl Surface { + pub unsafe fn raw_handle(&self) -> vk::SurfaceKHR { + self.raw + } + /// Get the raw Vulkan swapchain associated with this surface. /// /// Returns [`None`] if the surface is not configured. @@ -959,6 +963,13 @@ impl Texture { pub unsafe fn raw_handle(&self) -> vk::Image { self.raw } + + /// # Safety + /// + /// - The external memory must not be manually freed + pub unsafe fn external_memory(&self) -> Option<vk::DeviceMemory> { + self.external_memory + } } #[derive(Debug)] @@ -1001,13 +1012,25 @@ pub struct Sampler { impl crate::DynSampler for Sampler {} +/// Information about a binding within a specific BindGroupLayout / BindGroup. +/// This will be used to construct a [`naga::back::spv::BindingInfo`], where +/// the descriptor set value will be taken from the index of the group. +#[derive(Copy, Clone, Debug)] +struct BindingInfo { + binding: u32, + binding_array_size: Option<NonZeroU32>, +} + #[derive(Debug)] pub struct BindGroupLayout { raw: vk::DescriptorSetLayout, desc_count: gpu_descriptor::DescriptorTotalCount, - types: Box<[(vk::DescriptorType, u32)]>, - /// Map of binding index to size, - binding_arrays: Vec<(u32, NonZeroU32)>, + /// Sorted list of entries. + entries: Box<[wgt::BindGroupLayoutEntry]>, + /// Map of original binding index to remapped binding index and optional + /// array size. + binding_map: Vec<(u32, BindingInfo)>, + contains_binding_arrays: bool, } impl crate::DynBindGroupLayout for BindGroupLayout {} @@ -1015,7 +1038,7 @@ impl crate::DynBindGroupLayout for BindGroupLayout {} #[derive(Debug)] pub struct PipelineLayout { raw: vk::PipelineLayout, - binding_arrays: naga::back::spv::BindingMap, + binding_map: naga::back::spv::BindingMap, } impl crate::DynPipelineLayout for PipelineLayout {} diff --git a/third_party/rust/wgpu-types/.cargo-checksum.json b/third_party/rust/wgpu-types/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"1a325adbdf1fe020a0a93af94f247ea95e32a4d0d4c3a439c1bdb7e6dd32300a","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"e4d2d40bc1e870a59637f4b9574743e19565a62f6dbcc21cb18a76b666b796eb","src/cast_utils.rs":"33f03a57ccbedef2699f2305bec584c623db1fd28bfdf584d1260da4fbecd529","src/counters.rs":"e2a1c69126bdb6a35f74d5062e89e242eb955014d95c2b9e6e1b03f7b4b5bd98","src/env.rs":"26ffc91867625784159bcf391881187aa92cf92b81b1f40959ce1b96ae6d554d","src/error.rs":"0109e6209cf152abbfd0cee85dd934fb24f2304bf6adad6fb684b77f151fb158","src/features.rs":"ab880ecf55be2a93244d1a03119d10ee15eddc076f100ae03d13b51eaa815b57","src/instance.rs":"deeb5ca694163baf46c386316a498cee011cf960d48b749d4cd01125e9fca57f","src/lib.rs":"d9761963e424ee8f87ea43c754918b05e9d3326b621b20d5438167c328593b39","src/math.rs":"3046121800bded318b7d219aea401907e7d3bba3b998df6745a71e76f0734de2","src/tokens.rs":"cdf192e0c9b4ea4f3cd4148d07be2e895f937f8154acbf52caf67f7fb4df11dc","src/transfers.rs":"25f47e9cbc5887f849f5eb4d8952d89de6377df40f480ebbea61c58d2e0e7fc6"},"package":null} -\ No newline at end of file +{"files":{"Cargo.toml":"1a325adbdf1fe020a0a93af94f247ea95e32a4d0d4c3a439c1bdb7e6dd32300a","LICENSE.APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE.MIT":"c7fea58d1cfe49634cd92e54fc10a9d871f4b275321a4cd8c09e449122caaeb4","src/assertions.rs":"e4d2d40bc1e870a59637f4b9574743e19565a62f6dbcc21cb18a76b666b796eb","src/cast_utils.rs":"33f03a57ccbedef2699f2305bec584c623db1fd28bfdf584d1260da4fbecd529","src/counters.rs":"e2a1c69126bdb6a35f74d5062e89e242eb955014d95c2b9e6e1b03f7b4b5bd98","src/env.rs":"26ffc91867625784159bcf391881187aa92cf92b81b1f40959ce1b96ae6d554d","src/error.rs":"0109e6209cf152abbfd0cee85dd934fb24f2304bf6adad6fb684b77f151fb158","src/features.rs":"ab880ecf55be2a93244d1a03119d10ee15eddc076f100ae03d13b51eaa815b57","src/instance.rs":"deeb5ca694163baf46c386316a498cee011cf960d48b749d4cd01125e9fca57f","src/lib.rs":"bfb7d267d55e87b9d77c7ac2a822caba0554af26060a2cd37a25440d5c82be4f","src/math.rs":"3046121800bded318b7d219aea401907e7d3bba3b998df6745a71e76f0734de2","src/tokens.rs":"cdf192e0c9b4ea4f3cd4148d07be2e895f937f8154acbf52caf67f7fb4df11dc","src/transfers.rs":"25f47e9cbc5887f849f5eb4d8952d89de6377df40f480ebbea61c58d2e0e7fc6"},"package":null} +\ No newline at end of file diff --git a/third_party/rust/wgpu-types/src/lib.rs b/third_party/rust/wgpu-types/src/lib.rs @@ -5365,7 +5365,7 @@ bitflags::bitflags! { } /// A buffer transition for use with `CommandEncoder::transition_resources`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct BufferTransition<T> { /// The buffer to transition. pub buffer: T, @@ -5668,7 +5668,7 @@ bitflags::bitflags! { } /// A texture transition for use with `CommandEncoder::transition_resources`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct TextureTransition<T> { /// The texture to transition. pub texture: T, diff --git a/tools/lint/trojan-source.yml b/tools/lint/trojan-source.yml @@ -22,6 +22,7 @@ trojan-source: - third_party/rust/icu_provider/src/hello_world.rs - third_party/rust/icu_segmenter/src/grapheme.rs - third_party/rust/icu_segmenter/src/line.rs + - third_party/rust/ron/src/util/span_substring.rs - third_party/rust/unicode-width/src/lib.rs - third_party/rust/unicode-width/tests/tests.rs - security/nss/gtests/mozpkix_gtest/pkixnames_tests.cpp