From 90a5d6d9ce965716271c5b81eed0d6f139c99530 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 17:32:16 +0000 Subject: [PATCH 1/2] chore(deps): update rust crate wgc to v29 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4e343f30..09f62982 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ resolver = "2" [workspace.dependencies.wgc] package = "wgpu-core" -version = "27.0.3" +version = "29.0.0" [workspace.dependencies.wgt] package = "wgpu-types" From ef9c41d59b27c0cd4d8434a2911d088917c68d9d Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 8 Apr 2026 22:41:50 -0400 Subject: [PATCH 2/2] Fix --- .github/workflows/ci.yml | 10 +- CHANGELOG.md | 75 +++ Cargo.lock | 456 +++++++++--------- Cargo.toml | 12 +- Makefile | 20 +- README.md | 2 +- deny.toml | 2 - examples/CMakeLists.txt | 2 +- .../CMakeLists.txt | 6 +- .../{push_constants => immediates}/main.c | 27 +- .../shader.wgsl | 6 +- examples/metal_interop/main.c | 5 +- examples/texture_arrays/main.c | 6 +- ffi/wgpu.h | 369 +++++++++----- src/conv.rs | 146 ++++-- src/lib.rs | 82 ++-- 16 files changed, 737 insertions(+), 489 deletions(-) create mode 100644 CHANGELOG.md rename examples/{push_constants => immediates}/CMakeLists.txt (79%) rename examples/{push_constants => immediates}/main.c (93%) rename examples/{push_constants => immediates}/shader.wgsl (65%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58371757..cd749b8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: env: CI_RUST_VERSION: "1.91" - CI_RUST_MSRV: "1.82" + CI_RUST_MSRV: "1.87" CARGO_INCREMENTAL: false CARGO_TERM_COLOR: always RUST_BACKTRACE: full @@ -312,13 +312,13 @@ jobs: make example-triangle make example-enumerate_adapters make example-texture_arrays - make example-push_constants + make example-immediates - name: Run examples debug run: | make run-example-capture make run-example-compute make run-example-enumerate_adapters - make run-example-push_constants + make run-example-immediates - name: Build examples release run: | make example-capture-release @@ -326,10 +326,10 @@ jobs: make example-triangle-release make example-enumerate_adapters-release make example-texture_arrays-release - make example-push_constants-release + make example-immediates-release - name: Run examples release run: | make run-example-capture-release make run-example-compute-release make run-example-enumerate_adapters-release - make run-example-push_constants-release + make run-example-immediates-release diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..7213894f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,75 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +#### Table of Contents + +- [Unreleased](#unreleased) +- [Diffs](#diffs) + +## Unreleased + +### Changed + +- Updated all wgpu crates to v29 +- MSRV bumped from 1.82 to 1.87. +- **Push constants renamed to immediates.** This matches the upstream wgpu rename. + - `WGPUNativeFeature_PushConstants` -> `WGPUNativeFeature_Immediates` + - `WGPUNativeLimits::maxPushConstantSize` -> `WGPUNativeLimits::maxImmediateSize` + - `WGPUPipelineLayoutExtras` no longer takes an array of `WGPUPushConstantRange`. It now takes a single `uint32_t immediateDataSize` representing the total size in bytes. + ```c + // Before + WGPUPushConstantRange range = { .stages = WGPUShaderStage_Compute, .start = 0, .end = 4 }; + WGPUPipelineLayoutExtras extras = { + .chain = { .sType = WGPUSType_PipelineLayoutExtras }, + .pushConstantRangeCount = 1, + .pushConstantRanges = &range, + }; + + // After + WGPUPipelineLayoutExtras extras = { + .chain = { .sType = WGPUSType_PipelineLayoutExtras }, + .immediateDataSize = sizeof(uint32_t), + }; + ``` + - `wgpuRenderPassEncoderSetPushConstants` -> `wgpuRenderPassEncoderSetImmediates` (removed `stages` parameter) + - `wgpuComputePassEncoderSetPushConstants` -> `wgpuComputePassEncoderSetImmediates` + - `wgpuRenderBundleEncoderSetPushConstants` -> `wgpuRenderBundleEncoderSetImmediates` (removed `stages` parameter) + ```c + // Before + wgpuComputePassEncoderSetPushConstants(encoder, 0, sizeof(uint32_t), &data); + wgpuRenderPassEncoderSetPushConstants(encoder, WGPUShaderStage_Vertex, 0, sizeof(uint32_t), &data); + + // After + wgpuComputePassEncoderSetImmediates(encoder, 0, sizeof(uint32_t), &data); + wgpuRenderPassEncoderSetImmediates(encoder, 0, sizeof(uint32_t), &data); + ``` + - WGSL shaders must use `var` instead of `var`. +- `WGPUNativeFeature_ShaderPrimitiveIndex` removed. Use the standard `WGPUFeatureName_PrimitiveIndex` from `webgpu.h` instead. +- `wgpuQueueGetNativeMetalCommandQueue` now returns `NULL`. The raw `MTLCommandQueue` is no longer publicly accessible in wgpu-hal v29. + +### Added + +- `WGPUNativeDisplayHandle` tagged union for passing a platform display connection at instance creation. Set `WGPUInstanceExtras::displayHandle` to provide an Xlib, XCB, or Wayland display handle. Required by the GLES backend on Wayland; other backends ignore it. Zero-initialization yields `WGPUNativeDisplayHandleType_None`. + ```c + WGPUInstanceExtras extras = { + .chain = { .sType = WGPUSType_InstanceExtras }, + .displayHandle = { + .type = WGPUNativeDisplayHandleType_Wayland, + .data.wayland = { .display = wl_display }, + }, + }; + ``` +- `WGPUSurfaceGetCurrentTextureStatus_Occluded` native extension value for `WGPUSurfaceGetCurrentTextureStatus`. Returned by `wgpuSurfaceGetCurrentTexture` when the window is not visible (e.g. minimized or fully behind another window). Currently only produced by the Metal backend on macOS, where acquiring a drawable while occluded would otherwise block for up to one second waiting for vsync. When you receive this status, no texture is returned and the surface remains valid -- skip rendering for the current frame and retry once the window becomes visible again. No reconfiguration is needed. + +### Removed + +- `WGPUPushConstantRange` struct. +- `foreign-types-shared` dependency (no longer needed after Metal backend switched to `objc2`). +- `raw-window-handle` feature on `wgpu-core` dependency (removed upstream). + +## Diffs + +- [Unreleased](https://github.com/gfx-rs/wgpu-native/compare/v27.0.4.1...HEAD) diff --git a/Cargo.lock b/Cargo.lock index c23a4e8f..d06a3ce5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -66,18 +72,18 @@ dependencies = [ [[package]] name = "bit-set" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" [[package]] name = "bitflags" @@ -89,10 +95,13 @@ dependencies = [ ] [[package]] -name = "block" -version = "0.1.6" +name = "block2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] [[package]] name = "bumpalo" @@ -154,45 +163,37 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "unicode-width", ] [[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "crunchy" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "core-graphics-types" -version = "0.2.0" +name = "dispatch2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ "bitflags", - "core-foundation", - "libc", + "objc2", ] [[package]] -name = "crunchy" -version = "0.2.4" +name = "dlib" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" +dependencies = [ + "libloading", +] [[package]] name = "document-features" @@ -233,33 +234,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - [[package]] name = "gl_generator" version = "0.14.0" @@ -279,9 +253,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "glow" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" dependencies = [ "js-sys", "slotmap", @@ -298,34 +272,17 @@ dependencies = [ "gl_generator", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags", -] - [[package]] name = "gpu-allocator" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ + "ash", + "hashbrown 0.16.1", "log", "presser", - "thiserror 1.0.69", + "thiserror", "windows", ] @@ -377,6 +334,8 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", "serde", "serde_core", @@ -508,34 +467,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] -name = "malloc_buf" -version = "0.0.6" +name = "macro_rules_attribute" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" dependencies = [ - "libc", + "macro_rules_attribute-proc_macro", + "paste", ] [[package]] -name = "memchr" -version = "2.8.0" +name = "macro_rules_attribute-proc_macro" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" [[package]] -name = "metal" -version = "0.32.0" +name = "memchr" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" -dependencies = [ - "bitflags", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", -] +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "minimal-lexical" @@ -545,9 +496,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "naga" -version = "27.0.3" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" +checksum = "aa2630921705b9b01dcdd0b6864b9562ca3c1951eecd0f0c4f5f04f61e412647" dependencies = [ "arrayvec", "bit-set", @@ -568,7 +519,7 @@ dependencies = [ "rustc-hash 1.1.0", "serde", "spirv", - "thiserror 2.0.18", + "thiserror", "unicode-ident", ] @@ -602,12 +553,65 @@ dependencies = [ ] [[package]] -name = "objc" -version = "0.2.7" +name = "objc2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "malloc_buf", + "bitflags", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-metal", ] [[package]] @@ -732,6 +736,18 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-quartz-core", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -850,12 +866,15 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "spirv" -version = "0.3.0+sdk-1.3.268.0" +version = "0.4.0+sdk-1.4.341.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" dependencies = [ "bitflags", ] @@ -871,33 +890,13 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -980,6 +979,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wayland-sys" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.94" @@ -992,9 +1003,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.3" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" +checksum = "1e80ac6cf1895df6342f87d975162108f9d98772a0d74bc404ab7304ac29469e" dependencies = [ "arrayvec", "bit-set", @@ -1006,6 +1017,7 @@ dependencies = [ "hashbrown 0.16.1", "indexmap", "log", + "macro_rules_attribute", "naga", "once_cell", "parking_lot", @@ -1014,60 +1026,59 @@ dependencies = [ "rustc-hash 1.1.0", "serde", "smallvec", - "thiserror 2.0.18", + "thiserror", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", "wgpu-hal", + "wgpu-naga-bridge", "wgpu-types", ] [[package]] name = "wgpu-core-deps-apple" -version = "27.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" +checksum = "43acd053312501689cd92a01a9638d37f3e41a5fd9534875efa8917ee2d11ac0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" +checksum = "ef043bf135cc68b6f667c55ff4e345ce2b5924d75bad36a47921b0287ca4b24a" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" +checksum = "725d5c006a8c02967b6d93ef04f6537ec4593313e330cfe86d9d3f946eb90f28" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "27.0.4" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" +checksum = "89a47aef47636562f3937285af4c44b4b5b404b46577471411cc5313a921da7e" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", "bitflags", - "block", + "block2", "bytemuck", "cfg-if", "cfg_aliases", - "core-graphics-types", "glow", "glutin_wgl_sys", - "gpu-alloc", "gpu-allocator", "gpu-descriptor", "hashbrown 0.16.1", @@ -1076,33 +1087,48 @@ dependencies = [ "libc", "libloading", "log", - "metal", "naga", "ndk-sys", - "objc", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-metal", + "objc2-quartz-core", "once_cell", "ordered-float", "parking_lot", "profiling", "range-alloc", "raw-window-handle", + "raw-window-metal", "renderdoc-sys", "smallvec", - "thiserror 2.0.18", + "thiserror", "wasm-bindgen", + "wayland-sys", "web-sys", + "wgpu-naga-bridge", "wgpu-types", "windows", "windows-core", ] +[[package]] +name = "wgpu-naga-bridge" +version = "29.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4684f4410da0cf95a4cb63bb5edaac022461dedb6adf0b64d0d9b5f6890d51" +dependencies = [ + "naga", + "wgpu-types", +] + [[package]] name = "wgpu-native" version = "0.0.0" dependencies = [ "bindgen", "bitflags", - "foreign-types-shared", "log", "naga", "parking_lot", @@ -1110,7 +1136,7 @@ dependencies = [ "raw-window-handle", "serde", "smallvec", - "thiserror 2.0.18", + "thiserror", "wgpu-core", "wgpu-hal", "wgpu-types", @@ -1118,47 +1144,69 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "27.0.1" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" +checksum = "ec2675540fb1a5cfa5ef122d3d5f390e2c75711a0b946410f2d6ac3a0f77d1f6" dependencies = [ "bitflags", "bytemuck", "js-sys", "log", + "raw-window-handle", "serde", - "thiserror 2.0.18", "web-sys", ] [[package]] name = "windows" -version = "0.58.0" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ "windows-core", - "windows-targets", ] [[package]] name = "windows-core" -version = "0.58.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", + "windows-link", "windows-result", "windows-strings", - "windows-targets", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1167,9 +1215,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1183,87 +1231,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-result" -version = "0.2.0" +name = "windows-numerics" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-targets", + "windows-core", + "windows-link", ] [[package]] -name = "windows-strings" -version = "0.1.0" +name = "windows-result" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-result", - "windows-targets", + "windows-link", ] [[package]] -name = "windows-targets" -version = "0.52.6" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-link", ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" +name = "windows-threading" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] [[package]] name = "xml-rs" diff --git a/Cargo.toml b/Cargo.toml index 09f62982..dde9a8cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ authors = [ "Rajesh Malviya ", ] edition = "2021" -rust-version = "1.82" +rust-version = "1.87" description = "Native WebGPU implementation based on wgpu-core" homepage = "https://github.com/gfx-rs/wgpu-native" repository = "https://github.com/gfx-rs/wgpu-native" @@ -24,19 +24,19 @@ resolver = "2" [workspace.dependencies.wgc] package = "wgpu-core" -version = "29.0.0" +version = "29.0.1" [workspace.dependencies.wgt] package = "wgpu-types" -version = "27.0.1" +version = "29.0.1" [workspace.dependencies.hal] package = "wgpu-hal" -version = "27.0.4" +version = "29.0.1" [workspace.dependencies.naga] package = "naga" -version = "27.0.3" +version = "29.0.1" [lib] crate-type = ["cdylib", "staticlib"] @@ -101,7 +101,6 @@ replay = ["serde", "wgc/replay"] [dependencies.wgc] workspace = true -features = ["raw-window-handle"] [dependencies.hal] workspace = true @@ -131,7 +130,6 @@ thiserror = "2" parking_lot = "0.12" smallvec = "1" bitflags = "2" -foreign-types-shared = "0.3" [build-dependencies] bindgen = "0.72" diff --git a/Makefile b/Makefile index 52dc8193..fe328043 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,9 @@ endif lib-native lib-native-release \ example-capture example-compute example-triangle \ example-metal_interop \ - example-push_constants example-push_constants-release \ + example-immediates example-immediates-release \ example-metal_interop-release \ - run-example-push_constants run-example-push_constants-release \ + run-example-immediates run-example-immediates-release \ example-capture-release example-compute-release example-triangle-release \ run-example-capture run-example-compute run-example-triangle run-example-metal_interop \ run-example-capture-release run-example-compute-release run-example-triangle-release @@ -122,17 +122,17 @@ examples-debug: lib-native examples-release: lib-native-release cd examples && $(MKDIR_CMD) "build/RelWithDebInfo" && cd build/RelWithDebInfo && cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ../.. -example-push_constants: examples-debug - cd examples/build/Debug && cmake --build . --target push_constants +example-immediates: examples-debug + cd examples/build/Debug && cmake --build . --target immediates -run-example-push_constants: example-push_constants - cd examples/push_constants && "../build/Debug/push_constants/push_constants" +run-example-immediates: example-immediates + cd examples/immediates && "../build/Debug/immediates/immediates" -example-push_constants-release: examples-release - cd examples/build/RelWithDebInfo && cmake --build . --target push_constants +example-immediates-release: examples-release + cd examples/build/RelWithDebInfo && cmake --build . --target immediates -run-example-push_constants-release: example-push_constants-release - cd examples/push_constants && "../build/RelWithDebInfo/push_constants/push_constants" +run-example-immediates-release: example-immediates-release + cd examples/immediates && "../build/RelWithDebInfo/immediates/immediates" example-capture: examples-debug cd examples/build/Debug && cmake --build . --target capture diff --git a/README.md b/README.md index 815c6345..e47bd7f7 100644 --- a/README.md +++ b/README.md @@ -43,4 +43,4 @@ There's also a (small) [contributor guide](https://github.com/gfx-rs/wgpu-native ## Minimum Supported Rust Version -The minimum supported Rust version (MSRV) for wgpu-native is **1.82**. MSRV bumps are considered breaking changes. +The minimum supported Rust version (MSRV) for wgpu-native is **1.87**. MSRV bumps are considered breaking changes. diff --git a/deny.toml b/deny.toml index a706a883..5e6a1ba7 100644 --- a/deny.toml +++ b/deny.toml @@ -18,8 +18,6 @@ skip = [ { crate = "foldhash@0.1", reason = "hashbrown 0.15 vs 0.16 in wgpu deps" }, { crate = "hashbrown@0.15", reason = "gpu-descriptor and petgraph lag behind" }, { crate = "rustc-hash@1", reason = "wgpu deps still use v1" }, - { crate = "thiserror@1", reason = "wgpu deps still use v1" }, - { crate = "thiserror-impl@1", reason = "wgpu deps still use v1" }, ] [sources] diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ef6087c5..820d17e8 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,7 +32,7 @@ add_subdirectory(framework) add_subdirectory(capture) add_subdirectory(compute) add_subdirectory(enumerate_adapters) -add_subdirectory(push_constants) +add_subdirectory(immediates) add_subdirectory(metal_interop) add_subdirectory(texture_arrays) add_subdirectory(triangle) diff --git a/examples/push_constants/CMakeLists.txt b/examples/immediates/CMakeLists.txt similarity index 79% rename from examples/push_constants/CMakeLists.txt rename to examples/immediates/CMakeLists.txt index 0a4bf36e..210b154f 100644 --- a/examples/push_constants/CMakeLists.txt +++ b/examples/immediates/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.20) -project(push_constants LANGUAGES C) +project(immediates LANGUAGES C) -add_executable(push_constants main.c) +add_executable(immediates main.c) if (MSVC) add_compile_options(/W4) @@ -21,4 +21,4 @@ elseif(APPLE) set(OS_LIBRARIES "-framework Foundation -framework CoreFoundation -framework QuartzCore -framework Metal") endif() -target_link_libraries(push_constants framework ${WGPU_LIBRARY} ${OS_LIBRARIES}) +target_link_libraries(immediates framework ${WGPU_LIBRARY} ${OS_LIBRARIES}) diff --git a/examples/push_constants/main.c b/examples/immediates/main.c similarity index 93% rename from examples/push_constants/main.c rename to examples/immediates/main.c index c99b1db9..60e1148c 100644 --- a/examples/push_constants/main.c +++ b/examples/immediates/main.c @@ -5,7 +5,7 @@ #include "framework.h" #include "webgpu-headers/webgpu.h" -#define LOG_PREFIX "[push_constants]" +#define LOG_PREFIX "[immediates]" static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, @@ -23,7 +23,7 @@ static void handle_request_device(WGPURequestDeviceStatus status, UNUSED(userdata2) *(WGPUDevice *)userdata1 = device; } -static void handle_buffer_map(WGPUMapAsyncStatus status, +static void handle_buffer_map(WGPUMapAsyncStatus status, WGPUStringView message, void *userdata1, void *userdata2) { UNUSED(userdata1) @@ -56,7 +56,7 @@ int main(int argc, char *argv[]) { { .sType = WGPUSType_NativeLimits, }, - .maxPushConstantSize = 0, + .maxImmediateSize = 0, }; WGPULimits supported_limits = { .nextInChain = &supported_limits_extras.chain, @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) { wgpuAdapterGetLimits(adapter, &supported_limits); WGPUFeatureName requiredFeatures[] = { - WGPUNativeFeature_PushConstants, + WGPUNativeFeature_Immediates, }; WGPUDeviceDescriptor device_desc = { .label = {"compute_device", WGPU_STRLEN}, @@ -74,8 +74,8 @@ int main(int argc, char *argv[]) { }; WGPUDevice device = NULL; - wgpuAdapterRequestDevice(adapter, &device_desc, - (const WGPURequestDeviceCallbackInfo){ + wgpuAdapterRequestDevice(adapter, &device_desc, + (const WGPURequestDeviceCallbackInfo){ .callback = handle_request_device, .userdata1 = &device }); @@ -107,19 +107,12 @@ int main(int argc, char *argv[]) { }); assert(staging_buffer); - WGPUPushConstantRange push_constant_range = { - .stages = WGPUShaderStage_Compute, - .start = 0, - .end = sizeof(uint32_t), - }; - WGPUPipelineLayoutExtras pipeline_layout_extras = { .chain = { .sType = WGPUSType_PipelineLayoutExtras, }, - .pushConstantRangeCount = 1, - .pushConstantRanges = &push_constant_range, + .immediateDataSize = sizeof(uint32_t), }; WGPUBindGroupLayoutEntry bind_group_layout_entries[] = { @@ -199,9 +192,9 @@ int main(int argc, char *argv[]) { NULL); for (uint32_t i = 0; i < numbers_length; i++) { - uint32_t pushConst = i; - wgpuComputePassEncoderSetPushConstants(compute_pass_encoder, 0, - sizeof(uint32_t), &pushConst); + uint32_t immediate = i; + wgpuComputePassEncoderSetImmediates(compute_pass_encoder, 0, + sizeof(uint32_t), &immediate); wgpuComputePassEncoderDispatchWorkgroups(compute_pass_encoder, numbers_length, 1, 1); diff --git a/examples/push_constants/shader.wgsl b/examples/immediates/shader.wgsl similarity index 65% rename from examples/push_constants/shader.wgsl rename to examples/immediates/shader.wgsl index e0b86e42..69f1f67b 100644 --- a/examples/push_constants/shader.wgsl +++ b/examples/immediates/shader.wgsl @@ -2,14 +2,14 @@ @binding(0) var buffer: array; -struct PushConstants { +struct Immediates { i: u32, } -var push_constants: PushConstants; +var immediates: Immediates; @compute @workgroup_size(1) fn main(@builtin(global_invocation_id) global_id: vec3) { - let i = push_constants.i; + let i = immediates.i; buffer[i] = i * 2; } diff --git a/examples/metal_interop/main.c b/examples/metal_interop/main.c index d0925a72..bd0d7dc1 100644 --- a/examples/metal_interop/main.c +++ b/examples/metal_interop/main.c @@ -112,10 +112,13 @@ int main(int argc, char *argv[]) { int ok = 1; if (is_metal) { - if (!native_device || !native_queue || !native_texture) { + if (!native_device || !native_texture) { fprintf(stderr, LOG_PREFIX " expected non-null native Metal handles on Metal backend\n"); ok = 0; } + if (!native_queue) { + printf(LOG_PREFIX " native_queue is not available (wgpu-hal does not expose the raw MTLCommandQueue)\n"); + } } else { printf(LOG_PREFIX " non-Metal backend: skipping strict non-null check\n"); } diff --git a/examples/texture_arrays/main.c b/examples/texture_arrays/main.c index 6af428fc..eed8323b 100644 --- a/examples/texture_arrays/main.c +++ b/examples/texture_arrays/main.c @@ -527,7 +527,7 @@ int main(int argc, char *argv[]) { (const WGPUBindGroupEntry){ .binding = 0, .nextInChain = - (const WGPUChainedStruct *)&(const WGPUBindGroupEntryExtras){ + (WGPUChainedStruct *)&(WGPUBindGroupEntryExtras){ .chain = (const WGPUChainedStruct){ .sType = (WGPUSType)WGPUSType_BindGroupEntryExtras, @@ -543,7 +543,7 @@ int main(int argc, char *argv[]) { (const WGPUBindGroupEntry){ .binding = 1, .nextInChain = - (const WGPUChainedStruct *)&(const WGPUBindGroupEntryExtras){ + (WGPUChainedStruct *)&(WGPUBindGroupEntryExtras){ .chain = (const WGPUChainedStruct){ .sType = (WGPUSType)WGPUSType_BindGroupEntryExtras, @@ -559,7 +559,7 @@ int main(int argc, char *argv[]) { (const WGPUBindGroupEntry){ .binding = 2, .nextInChain = - (const WGPUChainedStruct *)&(const WGPUBindGroupEntryExtras){ + (WGPUChainedStruct *)&(WGPUBindGroupEntryExtras){ .chain = (const WGPUChainedStruct){ .sType = (WGPUSType)WGPUSType_BindGroupEntryExtras, diff --git a/ffi/wgpu.h b/ffi/wgpu.h index a24eb2fa..ad4fc0ec 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -3,7 +3,8 @@ #include "webgpu.h" -typedef enum WGPUNativeSType { +typedef enum WGPUNativeSType +{ // Start at 0003 since that's allocated range for wgpu-native WGPUSType_DeviceExtras = 0x00030001, WGPUSType_NativeLimits = 0x00030002, @@ -19,8 +20,41 @@ typedef enum WGPUNativeSType { WGPUNativeSType_Force32 = 0x7FFFFFFF } WGPUNativeSType; -typedef enum WGPUNativeFeature { - WGPUNativeFeature_PushConstants = 0x00030001, +typedef enum WGPUNativeSurfaceGetCurrentTextureStatus +{ + /** + * The surface texture was not acquired because the window is occluded + * (e.g. minimized or fully covered by another window). + * + * No texture is returned and the @c texture field of + * @c WGPUSurfaceTexture will be NULL. The surface and swapchain remain + * valid -- there is no need to reconfigure or recreate the surface. + * + * Applications should skip rendering for the current frame and try + * again once the window is no longer occluded. If you are using a + * windowing library such as winit, listen for the window's "occluded" + * event and request a new redraw when the window becomes visible again. + * + * When does this occur? + * + * Currently this status is only produced by the Metal backend on macOS. + * When a window is not visible (checked via the @c NSWindow + * @c occlusionState property), acquiring the next drawable would block + * for up to one second waiting for vsync. wgpu-native returns + * @c Occluded instead to avoid that hang. + * + * Other backends (Vulkan, DX12, GL) do not currently report this + * status; an occluded window on those backends may produce + * @c WGPUSurfaceGetCurrentTextureStatus_Timeout or simply succeed + * normally. + */ + WGPUSurfaceGetCurrentTextureStatus_Occluded = 0x00030001, + WGPUNativeSurfaceGetCurrentTextureStatus_Force32 = 0x7FFFFFFF +} WGPUNativeSurfaceGetCurrentTextureStatus; + +typedef enum WGPUNativeFeature +{ + WGPUNativeFeature_Immediates = 0x00030001, WGPUNativeFeature_TextureAdapterSpecificFormatFeatures = 0x00030002, WGPUNativeFeature_MultiDrawIndirectCount = 0x00030004, WGPUNativeFeature_VertexWritableStorage = 0x00030005, @@ -48,7 +82,6 @@ typedef enum WGPUNativeFeature { WGPUNativeFeature_RayQuery = 0x0003001C, WGPUNativeFeature_ShaderF64 = 0x0003001D, WGPUNativeFeature_ShaderI16 = 0x0003001E, - WGPUNativeFeature_ShaderPrimitiveIndex = 0x0003001F, WGPUNativeFeature_ShaderEarlyDepthTest = 0x00030020, WGPUNativeFeature_Subgroup = 0x00030021, WGPUNativeFeature_SubgroupVertex = 0x00030022, @@ -59,7 +92,8 @@ typedef enum WGPUNativeFeature { WGPUNativeFeature_Force32 = 0x7FFFFFFF } WGPUNativeFeature; -typedef enum WGPULogLevel { +typedef enum WGPULogLevel +{ WGPULogLevel_Off = 0x00000000, WGPULogLevel_Error = 0x00000001, WGPULogLevel_Warn = 0x00000002, @@ -98,14 +132,16 @@ static const WGPUInstanceFlag WGPUInstanceFlag_AdvancedDebugging = 1 << 26; static const WGPUInstanceFlag WGPUInstanceFlag_WithEnv = 1 << 27; static const WGPUInstanceFlag WGPUInstanceFlag_Force32 = 0x7FFFFFFF; -typedef enum WGPUDx12Compiler { +typedef enum WGPUDx12Compiler +{ WGPUDx12Compiler_Undefined = 0x00000000, WGPUDx12Compiler_Fxc = 0x00000001, WGPUDx12Compiler_Dxc = 0x00000002, WGPUDx12Compiler_Force32 = 0x7FFFFFFF } WGPUDx12Compiler; -typedef enum WGPUGles3MinorVersion { +typedef enum WGPUGles3MinorVersion +{ WGPUGles3MinorVersion_Automatic = 0x00000000, WGPUGles3MinorVersion_Version0 = 0x00000001, WGPUGles3MinorVersion_Version1 = 0x00000002, @@ -113,7 +149,8 @@ typedef enum WGPUGles3MinorVersion { WGPUGles3MinorVersion_Force32 = 0x7FFFFFFF } WGPUGles3MinorVersion; -typedef enum WGPUPipelineStatisticName { +typedef enum WGPUPipelineStatisticName +{ WGPUPipelineStatisticName_VertexShaderInvocations = 0x00000000, WGPUPipelineStatisticName_ClipperInvocations = 0x00000001, WGPUPipelineStatisticName_ClipperPrimitivesOut = 0x00000002, @@ -122,12 +159,14 @@ typedef enum WGPUPipelineStatisticName { WGPUPipelineStatisticName_Force32 = 0x7FFFFFFF } WGPUPipelineStatisticName WGPU_ENUM_ATTRIBUTE; -typedef enum WGPUNativeQueryType { +typedef enum WGPUNativeQueryType +{ WGPUNativeQueryType_PipelineStatistics = 0x00030000, WGPUNativeQueryType_Force32 = 0x7FFFFFFF } WGPUNativeQueryType WGPU_ENUM_ATTRIBUTE; -typedef enum WGPUDxcMaxShaderModel { +typedef enum WGPUDxcMaxShaderModel +{ WGPUDxcMaxShaderModel_V6_0 = 0x00000000, WGPUDxcMaxShaderModel_V6_1 = 0x00000001, WGPUDxcMaxShaderModel_V6_2 = 0x00000002, @@ -139,20 +178,97 @@ typedef enum WGPUDxcMaxShaderModel { WGPUDxcMaxShaderModel_Force32 = 0x7FFFFFFF } WGPUDxcMaxShaderModel; -typedef enum WGPUGLFenceBehaviour { +typedef enum WGPUGLFenceBehaviour +{ WGPUGLFenceBehaviour_Normal = 0x00000000, WGPUGLFenceBehaviour_AutoFinish = 0x00000001, WGPUGLFenceBehaviour_Force32 = 0x7FFFFFFF } WGPUGLFenceBehaviour; -typedef enum WGPUDx12SwapchainKind { +typedef enum WGPUDx12SwapchainKind +{ WGPUDx12SwapchainKind_Undefined = 0x00000000, WGPUDx12SwapchainKind_DxgiFromHwnd = 0x00000001, WGPUDx12SwapchainKind_DxgiFromVisual = 0x00000002, WGPUDx12SwapchainKind_Force32 = 0x7FFFFFFF } WGPUDx12SwapchainKind; -typedef struct WGPUInstanceExtras { +/** + * Discriminant for @ref WGPUNativeDisplayHandle. + * + * Identifies which platform's display connection is stored in the tagged union. + * Use @ref WGPUNativeDisplayHandleType_None (the default when zero-initialized) when + * no display handle is needed. Platforms with no display connection data (Windows, + * macOS, iOS, Android) should use @ref WGPUNativeDisplayHandleType_None. + */ +typedef enum WGPUNativeDisplayHandleType +{ + /** No display handle provided. */ + WGPUNativeDisplayHandleType_None = 0x00000000, + /** X11 display connection via Xlib. See @ref WGPUXlibDisplayHandle. */ + WGPUNativeDisplayHandleType_Xlib = 0x00000001, + /** X11 display connection via XCB. See @ref WGPUXcbDisplayHandle. */ + WGPUNativeDisplayHandleType_Xcb = 0x00000002, + /** Wayland display connection. See @ref WGPUWaylandDisplayHandle. */ + WGPUNativeDisplayHandleType_Wayland = 0x00000003, + WGPUNativeDisplayHandleType_Force32 = 0x7FFFFFFF +} WGPUNativeDisplayHandleType; + +/** + * Xlib display connection data for @ref WGPUNativeDisplayHandle. + */ +typedef struct WGPUXlibDisplayHandle +{ + /** Pointer to the X11 @c Display (i.e. @c Display*). Must not be NULL. */ + void *display; + /** X11 screen number. */ + int screen; +} WGPUXlibDisplayHandle; + +/** + * XCB display connection data for @ref WGPUNativeDisplayHandle. + */ +typedef struct WGPUXcbDisplayHandle +{ + /** Pointer to the XCB connection (i.e. @c xcb_connection_t*). Must not be NULL. */ + void *connection; + /** X11 screen number. */ + int screen; +} WGPUXcbDisplayHandle; + +/** + * Wayland display connection data for @ref WGPUNativeDisplayHandle. + */ +typedef struct WGPUWaylandDisplayHandle +{ + /** Pointer to the Wayland display (i.e. @c wl_display*). Must not be NULL. */ + void *display; +} WGPUWaylandDisplayHandle; + +/** + * Platform display connection, passed as a field of @ref WGPUInstanceExtras. + * + * This is a tagged union. Set @c type to indicate which variant is active, then + * populate the corresponding field in @c data. Zero-initialization yields + * @ref WGPUNativeDisplayHandleType_None, meaning no display handle is provided. + * + * Currently required by the GLES backend when presenting on Wayland. Other + * backends ignore this field. If the instance is created with a display handle, + * all surfaces created from it must use the same display connection. + */ +typedef struct WGPUNativeDisplayHandle +{ + WGPUNativeDisplayHandleType type; + union + { + WGPUXlibDisplayHandle xlib; + WGPUXcbDisplayHandle xcb; + WGPUWaylandDisplayHandle wayland; + } data; +} WGPUNativeDisplayHandle; + +typedef struct WGPUInstanceExtras +{ WGPUChainedStruct chain; WGPUInstanceBackend backends; WGPUInstanceFlag flags; @@ -163,64 +279,71 @@ typedef struct WGPUInstanceExtras { WGPUDxcMaxShaderModel dxcMaxShaderModel; WGPUDx12SwapchainKind dx12PresentationSystem; - WGPU_NULLABLE const uint8_t* budgetForDeviceCreation; - WGPU_NULLABLE const uint8_t* budgetForDeviceLoss; + WGPU_NULLABLE const uint8_t *budgetForDeviceCreation; + WGPU_NULLABLE const uint8_t *budgetForDeviceLoss; + + /** + * Platform display connection to associate with this instance. + * Zero-initialized yields @ref WGPUNativeDisplayHandleType_None (no handle). + */ + WGPUNativeDisplayHandle displayHandle; } WGPUInstanceExtras; -typedef struct WGPUDeviceExtras { +typedef struct WGPUDeviceExtras +{ WGPUChainedStruct chain; WGPUStringView tracePath; } WGPUDeviceExtras; -typedef struct WGPUNativeLimits { +typedef struct WGPUNativeLimits +{ /** This struct chain is used as mutable in some places and immutable in others. */ WGPUChainedStruct chain; - uint32_t maxPushConstantSize; + uint32_t maxImmediateSize; uint32_t maxNonSamplerBindings; uint32_t maxBindingArrayElementsPerShaderStage; } WGPUNativeLimits; -typedef struct WGPUPushConstantRange { - WGPUShaderStage stages; - uint32_t start; - uint32_t end; -} WGPUPushConstantRange; - -typedef struct WGPUPipelineLayoutExtras { +typedef struct WGPUPipelineLayoutExtras +{ WGPUChainedStruct chain; - size_t pushConstantRangeCount; - WGPUPushConstantRange const * pushConstantRanges; + uint32_t immediateDataSize; } WGPUPipelineLayoutExtras; typedef uint64_t WGPUSubmissionIndex; -typedef struct WGPUShaderDefine { +typedef struct WGPUShaderDefine +{ WGPUStringView name; WGPUStringView value; } WGPUShaderDefine; -typedef struct WGPUShaderSourceGLSL { +typedef struct WGPUShaderSourceGLSL +{ WGPUChainedStruct chain; WGPUShaderStage stage; WGPUStringView code; uint32_t defineCount; - WGPUShaderDefine const * defines; + WGPUShaderDefine const *defines; } WGPUShaderSourceGLSL; -typedef struct WGPUShaderModuleDescriptorSpirV { +typedef struct WGPUShaderModuleDescriptorSpirV +{ WGPUStringView label; uint32_t sourceSize; - uint32_t const * source; + uint32_t const *source; } WGPUShaderModuleDescriptorSpirV; -typedef struct WGPURegistryReport { - size_t numAllocated; - size_t numKeptFromUser; - size_t numReleasedFromUser; - size_t elementSize; +typedef struct WGPURegistryReport +{ + size_t numAllocated; + size_t numKeptFromUser; + size_t numReleasedFromUser; + size_t elementSize; } WGPURegistryReport; -typedef struct WGPUHubReport { +typedef struct WGPUHubReport +{ WGPURegistryReport adapters; WGPURegistryReport devices; WGPURegistryReport queues; @@ -240,69 +363,79 @@ typedef struct WGPUHubReport { WGPURegistryReport samplers; } WGPUHubReport; -typedef struct WGPUGlobalReport { +typedef struct WGPUGlobalReport +{ WGPURegistryReport surfaces; WGPUHubReport hub; } WGPUGlobalReport; -typedef struct WGPUInstanceEnumerateAdapterOptions { - WGPUChainedStruct const * nextInChain; +typedef struct WGPUInstanceEnumerateAdapterOptions +{ + WGPUChainedStruct const *nextInChain; WGPUInstanceBackend backends; } WGPUInstanceEnumerateAdapterOptions; -typedef struct WGPUBindGroupEntryExtras { +typedef struct WGPUBindGroupEntryExtras +{ WGPUChainedStruct chain; - WGPUBuffer const * buffers; + WGPUBuffer const *buffers; size_t bufferCount; - WGPUSampler const * samplers; + WGPUSampler const *samplers; size_t samplerCount; - WGPUTextureView const * textureViews; + WGPUTextureView const *textureViews; size_t textureViewCount; } WGPUBindGroupEntryExtras; -typedef struct WGPUBindGroupLayoutEntryExtras { +typedef struct WGPUBindGroupLayoutEntryExtras +{ WGPUChainedStruct chain; uint32_t count; } WGPUBindGroupLayoutEntryExtras; -typedef struct WGPUQuerySetDescriptorExtras { +typedef struct WGPUQuerySetDescriptorExtras +{ WGPUChainedStruct chain; - WGPUPipelineStatisticName const * pipelineStatistics; + WGPUPipelineStatisticName const *pipelineStatistics; size_t pipelineStatisticCount; } WGPUQuerySetDescriptorExtras WGPU_STRUCTURE_ATTRIBUTE; -typedef struct WGPUSurfaceConfigurationExtras { +typedef struct WGPUSurfaceConfigurationExtras +{ WGPUChainedStruct chain; uint32_t desiredMaximumFrameLatency; } WGPUSurfaceConfigurationExtras WGPU_STRUCTURE_ATTRIBUTE; /** -* Chained in @ref WGPUSurfaceDescriptor to make a @ref WGPUSurface wrapping a WinUI [`SwapChainPanel`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.swapchainpanel). -*/ -typedef struct WGPUSurfaceSourceSwapChainPanel { + * Chained in @ref WGPUSurfaceDescriptor to make a @ref WGPUSurface wrapping a WinUI [`SwapChainPanel`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.swapchainpanel). + */ +typedef struct WGPUSurfaceSourceSwapChainPanel +{ WGPUChainedStruct chain; /** - * A pointer to the [`ISwapChainPanelNative`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.xaml.media.dxinterop/nn-microsoft-ui-xaml-media-dxinterop-iswapchainpanelnative) - * interface of the SwapChainPanel that will be wrapped by the @ref WGPUSurface. - */ - void * panelNative; + * A pointer to the [`ISwapChainPanelNative`](https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.xaml.media.dxinterop/nn-microsoft-ui-xaml-media-dxinterop-iswapchainpanelnative) + * interface of the SwapChainPanel that will be wrapped by the @ref WGPUSurface. + */ + void *panelNative; } WGPUSurfaceSourceSwapChainPanel WGPU_STRUCTURE_ATTRIBUTE; -typedef enum WGPUPolygonMode { +typedef enum WGPUPolygonMode +{ WGPUPolygonMode_Fill = 0, WGPUPolygonMode_Line = 1, WGPUPolygonMode_Point = 2, } WGPUPolygonMode; -typedef struct WGPUPrimitiveStateExtras { +typedef struct WGPUPrimitiveStateExtras +{ WGPUChainedStruct chain; WGPUPolygonMode polygonMode; WGPUBool conservative; } WGPUPrimitiveStateExtras WGPU_STRUCTURE_ATTRIBUTE; -typedef void (*WGPULogCallback)(WGPULogLevel level, WGPUStringView message, void * userdata); +typedef void (*WGPULogCallback)(WGPULogLevel level, WGPUStringView message, void *userdata); -typedef enum WGPUNativeTextureFormat { +typedef enum WGPUNativeTextureFormat +{ // From Features::TEXTURE_FORMAT_16BIT_NORM WGPUNativeTextureFormat_R16Unorm = 0x00030001, WGPUNativeTextureFormat_R16Snorm = 0x00030002, @@ -315,75 +448,75 @@ typedef enum WGPUNativeTextureFormat { WGPUNativeTextureFormat_P010 = 0x00030008, } WGPUNativeTextureFormat; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -void wgpuGenerateReport(WGPUInstance instance, WGPUGlobalReport * report); -size_t wgpuInstanceEnumerateAdapters(WGPUInstance instance, WGPU_NULLABLE WGPUInstanceEnumerateAdapterOptions const * options, WGPUAdapter * adapters); - -WGPUSubmissionIndex wgpuQueueSubmitForIndex(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const * commands); -float wgpuQueueGetTimestampPeriod(WGPUQueue queue); - -// Returns true if the queue is empty, or false if there are more queue submissions still in flight. -WGPUBool wgpuDevicePoll(WGPUDevice device, WGPUBool wait, WGPU_NULLABLE WGPUSubmissionIndex const * submissionIndex); -WGPUShaderModule wgpuDeviceCreateShaderModuleSpirV(WGPUDevice device, WGPUShaderModuleDescriptorSpirV const * descriptor); - -void wgpuSetLogCallback(WGPULogCallback callback, void * userdata); - -void wgpuSetLogLevel(WGPULogLevel level); - -uint32_t wgpuGetVersion(void); - -/** - * Returns the backend-native `id` as an opaque pointer. - * - * The returned pointer is borrowed and remains valid only while `device` is alive. - * Ownership is retained by wgpu-native; callers must not release or destroy it. - * Returns NULL when the active backend is not Metal or when the handle is unavailable. - */ -void* wgpuDeviceGetNativeMetalDevice(WGPUDevice device); + void wgpuGenerateReport(WGPUInstance instance, WGPUGlobalReport *report); + size_t wgpuInstanceEnumerateAdapters(WGPUInstance instance, WGPU_NULLABLE WGPUInstanceEnumerateAdapterOptions const *options, WGPUAdapter *adapters); -/** - * Returns the backend-native `id` as an opaque pointer. - * - * The returned pointer is borrowed and remains valid only while `queue` is alive. - * Ownership is retained by wgpu-native; callers must not release or destroy it. - * Returns NULL when the active backend is not Metal or when the handle is unavailable. - */ -void* wgpuQueueGetNativeMetalCommandQueue(WGPUQueue queue); + WGPUSubmissionIndex wgpuQueueSubmitForIndex(WGPUQueue queue, size_t commandCount, WGPUCommandBuffer const *commands); + float wgpuQueueGetTimestampPeriod(WGPUQueue queue); -/** - * Returns the backend-native `id` as an opaque pointer. - * - * The returned pointer is borrowed and remains valid only while `texture` is alive. - * Ownership is retained by wgpu-native; callers must not release or destroy it. - * Returns NULL when the active backend is not Metal or when the handle is unavailable. - */ -void* wgpuTextureGetNativeMetalTexture(WGPUTexture texture); + // Returns true if the queue is empty, or false if there are more queue submissions still in flight. + WGPUBool wgpuDevicePoll(WGPUDevice device, WGPUBool wait, WGPU_NULLABLE WGPUSubmissionIndex const *submissionIndex); + WGPUShaderModule wgpuDeviceCreateShaderModuleSpirV(WGPUDevice device, WGPUShaderModuleDescriptorSpirV const *descriptor); -void wgpuRenderPassEncoderSetPushConstants(WGPURenderPassEncoder encoder, WGPUShaderStage stages, uint32_t offset, uint32_t sizeBytes, void const * data); -void wgpuComputePassEncoderSetPushConstants(WGPUComputePassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const * data); -void wgpuRenderBundleEncoderSetPushConstants(WGPURenderBundleEncoder encoder, WGPUShaderStage stages, uint32_t offset, uint32_t sizeBytes, void const * data); + void wgpuSetLogCallback(WGPULogCallback callback, void *userdata); -void wgpuRenderPassEncoderMultiDrawIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); -void wgpuRenderPassEncoderMultiDrawIndexedIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); + void wgpuSetLogLevel(WGPULogLevel level); -void wgpuRenderPassEncoderMultiDrawIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); -void wgpuRenderPassEncoderMultiDrawIndexedIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); + uint32_t wgpuGetVersion(void); -void wgpuComputePassEncoderBeginPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); -void wgpuComputePassEncoderEndPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder); -void wgpuRenderPassEncoderBeginPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); -void wgpuRenderPassEncoderEndPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder); + /** + * Returns the backend-native `id` as an opaque pointer. + * + * The returned pointer is borrowed and remains valid only while `device` is alive. + * Ownership is retained by wgpu-native; callers must not release or destroy it. + * Returns NULL when the active backend is not Metal or when the handle is unavailable. + */ + void *wgpuDeviceGetNativeMetalDevice(WGPUDevice device); -void wgpuComputePassEncoderWriteTimestamp(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); -void wgpuRenderPassEncoderWriteTimestamp(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); + /** + * Returns the backend-native `id` as an opaque pointer. + * + * The returned pointer is borrowed and remains valid only while `queue` is alive. + * Ownership is retained by wgpu-native; callers must not release or destroy it. + * Returns NULL when the active backend is not Metal or when the handle is unavailable. + */ + void *wgpuQueueGetNativeMetalCommandQueue(WGPUQueue queue); -// Returns true if the capture was successfully started, or false if it failed to start or is not supported on the current platform. -WGPUBool wgpuDeviceStartGraphicsDebuggerCapture(WGPUDevice device); -void wgpuDeviceStopGraphicsDebuggerCapture(WGPUDevice device); + /** + * Returns the backend-native `id` as an opaque pointer. + * + * The returned pointer is borrowed and remains valid only while `texture` is alive. + * Ownership is retained by wgpu-native; callers must not release or destroy it. + * Returns NULL when the active backend is not Metal or when the handle is unavailable. + */ + void *wgpuTextureGetNativeMetalTexture(WGPUTexture texture); + + void wgpuRenderPassEncoderSetImmediates(WGPURenderPassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data); + void wgpuComputePassEncoderSetImmediates(WGPUComputePassEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data); + void wgpuRenderBundleEncoderSetImmediates(WGPURenderBundleEncoder encoder, uint32_t offset, uint32_t sizeBytes, void const *data); + + void wgpuRenderPassEncoderMultiDrawIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); + void wgpuRenderPassEncoderMultiDrawIndexedIndirect(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, uint32_t count); + + void wgpuRenderPassEncoderMultiDrawIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); + void wgpuRenderPassEncoderMultiDrawIndexedIndirectCount(WGPURenderPassEncoder encoder, WGPUBuffer buffer, uint64_t offset, WGPUBuffer count_buffer, uint64_t count_buffer_offset, uint32_t max_count); + + void wgpuComputePassEncoderBeginPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); + void wgpuComputePassEncoderEndPipelineStatisticsQuery(WGPUComputePassEncoder computePassEncoder); + void wgpuRenderPassEncoderBeginPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); + void wgpuRenderPassEncoderEndPipelineStatisticsQuery(WGPURenderPassEncoder renderPassEncoder); + + void wgpuComputePassEncoderWriteTimestamp(WGPUComputePassEncoder computePassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); + void wgpuRenderPassEncoderWriteTimestamp(WGPURenderPassEncoder renderPassEncoder, WGPUQuerySet querySet, uint32_t queryIndex); + + // Returns true if the capture was successfully started, or false if it failed to start or is not supported on the current platform. + WGPUBool wgpuDeviceStartGraphicsDebuggerCapture(WGPUDevice device); + void wgpuDeviceStopGraphicsDebuggerCapture(WGPUDevice device); #ifdef __cplusplus } // extern "C" diff --git a/src/conv.rs b/src/conv.rs index fc9535b5..9a97ab16 100644 --- a/src/conv.rs +++ b/src/conv.rs @@ -5,6 +5,31 @@ use std::borrow::Cow; use std::num::{NonZeroIsize, NonZeroU32, NonZeroU64}; use std::ptr::NonNull; +/// Wrapper around a [`raw_window_handle::RawDisplayHandle`] that implements +/// [`raw_window_handle::HasDisplayHandle`] so it can be stored as a +/// `Box` in an [`wgt::InstanceDescriptor`]. +/// +/// # Safety +/// +/// The caller must ensure the underlying display connection outlives the +/// instance created with this handle. +#[derive(Debug, Clone, Copy)] +struct NativeDisplayHandle(raw_window_handle::RawDisplayHandle); + +// SAFETY: Display handle pointers are required to remain valid and thread-safe +// for the lifetime of the wgpu instance. +unsafe impl Send for NativeDisplayHandle {} +unsafe impl Sync for NativeDisplayHandle {} + +impl raw_window_handle::HasDisplayHandle for NativeDisplayHandle { + fn display_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + // SAFETY: The caller of map_instance_descriptor guarantees validity. + Ok(unsafe { raw_window_handle::DisplayHandle::borrow_raw(self.0) }) + } +} + map_enum_with_undefined!( map_store_op, WGPUStoreOp, @@ -33,7 +58,7 @@ map_enum_with_undefined!( map_enum_with_undefined!( map_mipmap_filter_mode, WGPUMipmapFilterMode, - wgt::FilterMode, + wgt::MipmapFilterMode, "Unknown mipmap filter mode", Nearest, Linear @@ -319,21 +344,6 @@ pub fn map_instance_flags(flags: native::WGPUInstanceFlag) -> wgt::InstanceFlags result } -map_enum!( - map_dxc_max_shader_model, - WGPUDxcMaxShaderModel, - wgt::DxcShaderModel, - "Unknown shader model version", - V6_0, - V6_1, - V6_2, - V6_3, - V6_4, - V6_5, - V6_6, - V6_7 -); - map_enum!( map_gl_fence_behavior, WGPUGLFenceBehaviour, @@ -354,7 +364,6 @@ pub unsafe fn map_instance_descriptor( native::WGPUDx12Compiler_Dxc => match string_view_into_str(extras.dxcPath) { Some(dxc_path) => wgt::Dx12Compiler::DynamicDxc { dxc_path: dxc_path.to_string(), - max_shader_model: map_dxc_max_shader_model(extras.dxcMaxShaderModel), }, _ => wgt::Dx12Compiler::StaticDxc, }, @@ -370,12 +379,15 @@ pub unsafe fn map_instance_descriptor( let for_resource_creation = unsafe { extras.budgetForDeviceCreation.as_ref() }.copied(); let for_device_loss = unsafe { extras.budgetForDeviceCreation.as_ref() }.copied(); + let display = map_native_display_handle(&extras.displayHandle); + wgt::InstanceDescriptor { backends: map_instance_backend_flags(extras.backends as native::WGPUInstanceBackend), backend_options: wgt::BackendOptions { gl: wgt::GlBackendOptions { gles_minor_version: map_gles3_minor_version(extras.gles3MinorVersion), fence_behavior: map_gl_fence_behavior(extras.glFenceBehaviour), + debug_fns: Default::default(), }, dx12: wgt::Dx12BackendOptions { shader_compiler: dx12_shader_compiler, @@ -389,12 +401,57 @@ pub unsafe fn map_instance_descriptor( for_device_loss, for_resource_creation, }, + display, } } else { - wgt::InstanceDescriptor::default() + wgt::InstanceDescriptor::new_without_display_handle() } } +/// Convert a C [`native::WGPUNativeDisplayHandle`] tagged union into an +/// optional boxed display handle suitable for [`wgt::InstanceDescriptor::display`]. +/// +/// # Safety +/// +/// Pointer fields inside the active union variant must be valid and non-null +/// when the type is not `None`. +unsafe fn map_native_display_handle( + handle: &native::WGPUNativeDisplayHandle, +) -> Option> { + let raw = match handle.type_ { + native::WGPUNativeDisplayHandleType_None => return None, + native::WGPUNativeDisplayHandleType_Xlib => { + let xlib = unsafe { &handle.data.xlib }; + let display = NonNull::new(xlib.display) + .expect("WGPUXlibDisplayHandle::display must not be NULL"); + raw_window_handle::RawDisplayHandle::Xlib(raw_window_handle::XlibDisplayHandle::new( + Some(display), + xlib.screen, + )) + } + native::WGPUNativeDisplayHandleType_Xcb => { + let xcb = unsafe { &handle.data.xcb }; + let connection = NonNull::new(xcb.connection) + .expect("WGPUXcbDisplayHandle::connection must not be NULL"); + raw_window_handle::RawDisplayHandle::Xcb(raw_window_handle::XcbDisplayHandle::new( + Some(connection), + xcb.screen, + )) + } + native::WGPUNativeDisplayHandleType_Wayland => { + let wl = unsafe { &handle.data.wayland }; + let display = NonNull::new(wl.display) + .expect("WGPUWaylandDisplayHandle::display must not be NULL"); + raw_window_handle::RawDisplayHandle::Wayland( + raw_window_handle::WaylandDisplayHandle::new(display), + ) + } + other => panic!("unknown WGPUNativeDisplayHandleType: {other}"), + }; + + Some(Box::new(NativeDisplayHandle(raw))) +} + #[inline] pub(crate) unsafe fn map_device_descriptor<'a>( des: &native::WGPUDeviceDescriptor, @@ -443,28 +500,21 @@ pub unsafe fn map_pipeline_layout_descriptor<'a>( let bind_group_layouts = make_slice(des.bindGroupLayouts, des.bindGroupLayoutCount) .iter() .map(|layout| { - layout - .as_ref() - .expect("invalid bind group layout for pipeline layout descriptor") - .id + Some( + layout + .as_ref() + .expect("invalid bind group layout for pipeline layout descriptor") + .id, + ) }) .collect::>(); - let push_constant_ranges = extras.map_or(Vec::new(), |extras| { - make_slice(extras.pushConstantRanges, extras.pushConstantRangeCount) - .iter() - .map(|range| wgt::PushConstantRange { - stages: from_u64_bits(range.stages) - .expect("invalid shader stage for push constant range"), - range: range.start..range.end, - }) - .collect() - }); + let immediate_size = extras.map_or(0, |extras| extras.immediateDataSize); wgc::binding_model::PipelineLayoutDescriptor { label: string_view_into_label(des.label), bind_group_layouts: Cow::from(bind_group_layouts), - push_constant_ranges: Cow::from(push_constant_ranges), + immediate_size, } } @@ -516,7 +566,7 @@ pub fn write_limits_struct(wgt_limits: wgt::Limits, limits: &mut native::WGPULim *mut native::WGPUChainedStruct, *mut native::WGPUNativeLimits, >(limits.nextInChain); - (*native_limits).maxPushConstantSize = wgt_limits.max_push_constant_size; + (*native_limits).maxImmediateSize = wgt_limits.max_immediate_size; (*native_limits).maxNonSamplerBindings = wgt_limits.max_non_sampler_bindings; (*native_limits).maxBindingArrayElementsPerShaderStage = wgt_limits.max_binding_array_elements_per_shader_stage; @@ -577,10 +627,10 @@ pub fn map_required_limits( wgt_limits.max_uniform_buffers_per_shader_stage = limits.maxUniformBuffersPerShaderStage; } if limits.maxUniformBufferBindingSize != WGPU_LIMIT_U64_UNDEFINED { - wgt_limits.max_uniform_buffer_binding_size = limits.maxUniformBufferBindingSize as u32; + wgt_limits.max_uniform_buffer_binding_size = limits.maxUniformBufferBindingSize; } if limits.maxStorageBufferBindingSize != WGPU_LIMIT_U64_UNDEFINED { - wgt_limits.max_storage_buffer_binding_size = limits.maxStorageBufferBindingSize as u32; + wgt_limits.max_storage_buffer_binding_size = limits.maxStorageBufferBindingSize; } if limits.minUniformBufferOffsetAlignment != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.min_uniform_buffer_offset_alignment = limits.minUniformBufferOffsetAlignment; @@ -629,8 +679,8 @@ pub fn map_required_limits( wgt_limits.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension; } if let Some(limits) = extras { - if limits.maxPushConstantSize != native::WGPU_LIMIT_U32_UNDEFINED { - wgt_limits.max_push_constant_size = limits.maxPushConstantSize; + if limits.maxImmediateSize != native::WGPU_LIMIT_U32_UNDEFINED { + wgt_limits.max_immediate_size = limits.maxImmediateSize; } if limits.maxNonSamplerBindings != native::WGPU_LIMIT_U32_UNDEFINED { wgt_limits.max_non_sampler_bindings = limits.maxNonSamplerBindings; @@ -1168,8 +1218,8 @@ pub fn features_to_native(features: wgt::Features) -> Vec Vec Option { // TODO: WGPUFeatureName_Float32Blendable native::WGPUFeatureName_Float32Filterable => Some(Features::FLOAT32_FILTERABLE), native::WGPUFeatureName_DualSourceBlending => Some(Features::DUAL_SOURCE_BLENDING), + native::WGPUFeatureName_PrimitiveIndex => Some(Features::PRIMITIVE_INDEX), // wgpu-rs only features - native::WGPUNativeFeature_PushConstants => Some(Features::PUSH_CONSTANTS), + native::WGPUNativeFeature_Immediates => Some(Features::IMMEDIATES), native::WGPUNativeFeature_TextureAdapterSpecificFormatFeatures => Some(Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES), native::WGPUNativeFeature_MultiDrawIndirectCount => Some(Features::MULTI_DRAW_INDIRECT_COUNT), native::WGPUNativeFeature_VertexWritableStorage => Some(Features::VERTEX_WRITABLE_STORAGE), @@ -1334,7 +1385,6 @@ pub fn map_feature(feature: native::WGPUFeatureName) -> Option { native::WGPUNativeFeature_RayQuery => Some(Features::EXPERIMENTAL_RAY_QUERY), native::WGPUNativeFeature_ShaderF64 => Some(Features::SHADER_F64), native::WGPUNativeFeature_ShaderInt64 => Some(Features::SHADER_INT64), - native::WGPUNativeFeature_ShaderPrimitiveIndex => Some(Features::SHADER_PRIMITIVE_INDEX), native::WGPUNativeFeature_ShaderEarlyDepthTest => Some(Features::SHADER_EARLY_DEPTH_TEST), native::WGPUNativeFeature_Subgroup => Some(Features::SUBGROUP), native::WGPUNativeFeature_SubgroupVertex => Some(Features::SUBGROUP_VERTEX), @@ -1383,7 +1433,7 @@ pub fn map_bind_group_entry<'a>( size: match entry.size { 0 => panic!("invalid size"), WGPU_WHOLE_SIZE => None, - _ => Some(unsafe { NonZeroU64::new_unchecked(entry.size) }), + _ => Some(entry.size), }, }, ), @@ -1433,7 +1483,11 @@ pub fn map_bind_group_entry<'a>( .expect("invalid buffers for bind group entry extras") .id, offset: entry.offset, - size: std::num::NonZeroU64::new(entry.size), + size: if entry.size == 0 { + None + } else { + Some(entry.size) + }, }) .collect(); return wgc::binding_model::BindGroupEntry { diff --git a/src/lib.rs b/src/lib.rs index 4d768045..7488e584 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,6 @@ use conv::{ map_query_set_index, map_shader_module, map_surface, map_surface_configuration, CreateSurfaceParams, }; -#[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))] -use foreign_types_shared::ForeignType as _; use parking_lot::Mutex; use smallvec::SmallVec; use std::{ @@ -392,7 +390,7 @@ impl Drop for WGPUTextureViewImpl { fn drop(&mut self) { if !thread::panicking() { let context = &self.context; - let _ = context.texture_view_drop(self.id); + context.texture_view_drop(self.id); } } } @@ -664,11 +662,11 @@ pub unsafe extern "C" fn wgpuCreateInstance( WGPUSType_InstanceExtras => native::WGPUInstanceExtras )) } - None => wgt::InstanceDescriptor::default(), + None => wgt::InstanceDescriptor::new_without_display_handle(), }; Arc::into_raw(Arc::new(WGPUInstanceImpl { - context: Arc::new(Context::new("wgpu", &instance_desc)), + context: Arc::new(Context::new("wgpu", instance_desc, None)), })) } @@ -1252,6 +1250,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderBeginRenderPass( depth_stencil_attachment: depth_stencil_attachment.as_ref(), timestamp_writes: timestamp_writes.as_ref(), occlusion_query_set: descriptor.occlusionQuerySet.as_ref().map(|v| v.id), + multiview_mask: None, }; let (pass, err) = context.command_encoder_begin_render_pass(command_encoder_id, &desc); @@ -1453,7 +1452,7 @@ pub unsafe extern "C" fn wgpuCommandEncoderFinish( let (command_buffer_id, error) = context.command_encoder_finish(command_encoder_id, &desc, None); - if let Some(cause) = error { + if let Some((_label, cause)) = error { handle_error(error_sink, cause, None, "wgpuCommandEncoderFinish"); } @@ -2153,7 +2152,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderBundleEncoder( multiview: None, }; - match wgc::command::RenderBundleEncoder::new(&desc, device_id, None) { + match wgc::command::RenderBundleEncoder::new(&desc, device_id) { Ok(encoder) => Arc::into_raw(Arc::new(WGPURenderBundleEncoderImpl { context: context.clone(), encoder: Box::into_raw(Box::new(Some(Box::into_raw(Box::new(encoder))))), @@ -2249,11 +2248,13 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( wgt::DepthStencilState { format, - depth_write_enabled: desc.depthWriteEnabled == native::WGPUOptionalBool_True, + depth_write_enabled: Some(desc.depthWriteEnabled == native::WGPUOptionalBool_True), // TODO: Is validation correct if we return always for undefined depth compare? - depth_compare: conv::map_compare_function(desc.depthCompare) - .expect("invalid depth compare function for depth stencil state") - .unwrap_or(wgt::CompareFunction::Always), + depth_compare: Some( + conv::map_compare_function(desc.depthCompare) + .expect("invalid depth compare function for depth stencil state") + .unwrap_or(wgt::CompareFunction::Always), + ), stencil: wgt::StencilState { front: conv::map_stencil_face_state(desc.stencilFront, "front"), back: conv::map_stencil_face_state(desc.stencilBack, "back"), @@ -2317,7 +2318,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateRenderPipeline( ), }), // TODO(wgpu.h) - multiview: None, + multiview_mask: None, // TODO(wgpu.h) cache: None, }; @@ -2369,7 +2370,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateSampler( min_filter: conv::map_filter_mode(descriptor.minFilter) .unwrap_or(wgt::FilterMode::Nearest), mipmap_filter: conv::map_mipmap_filter_mode(descriptor.mipmapFilter) - .unwrap_or(wgt::FilterMode::Nearest), + .unwrap_or(wgt::MipmapFilterMode::Nearest), lod_min_clamp: descriptor.lodMinClamp, lod_max_clamp: descriptor.lodMaxClamp, compare: conv::map_compare_function(descriptor.compare) @@ -2390,7 +2391,7 @@ pub unsafe extern "C" fn wgpuDeviceCreateSampler( ], mag_filter: wgt::FilterMode::Nearest, min_filter: wgt::FilterMode::Nearest, - mipmap_filter: wgt::FilterMode::Nearest, + mipmap_filter: wgt::MipmapFilterMode::Nearest, lod_min_clamp: 0f32, lod_max_clamp: 32f32, compare: None, @@ -2619,8 +2620,7 @@ pub unsafe extern "C" fn wgpuDeviceGetNativeMetalDevice(device: native::WGPUDevi let device = device.as_ref().expect("invalid device"); let hal_device = device.context.device_as_hal::(device.id); if let Some(hal_device) = hal_device { - let raw_device = hal_device.raw_device().lock(); - return raw_device.as_ptr().cast(); + return &**hal_device.raw_device() as *const _ as *mut c_void; } std::ptr::null_mut() } @@ -2748,7 +2748,7 @@ pub unsafe extern "C" fn wgpuInstanceCreateSurface( let surface_id = match create_surface_params { CreateSurfaceParams::Raw((rdh, rwh)) => { - match context.instance_create_surface(rdh, rwh, None) { + match context.instance_create_surface(Some(rdh), rwh, None) { Ok(surface_id) => surface_id, Err(cause) => handle_error_fatal(cause, "wgpuInstanceCreateSurface"), } @@ -3053,14 +3053,12 @@ pub unsafe extern "C" fn wgpuQueueGetNativeMetalCommandQueue( #[cfg(all(any(target_os = "ios", target_os = "macos"), feature = "metal"))] { let queue = queue.as_ref().expect("invalid queue"); - let hal_queue = queue - .queue - .context - .queue_as_hal::(queue.queue.id); - if let Some(hal_queue) = hal_queue { - let raw_queue = hal_queue.as_raw().lock(); - return raw_queue.as_ptr().cast(); - } + // wgpu-hal v29 no longer exposes a public accessor for the raw + // MTLCommandQueue. Return null until upstream adds one back. + log::warn!( + "wgpuQueueGetNativeMetalCommandQueue: not available in current wgpu-hal version" + ); + let _ = queue; std::ptr::null_mut() } #[cfg(not(all(any(target_os = "ios", target_os = "macos"), feature = "metal")))] @@ -4137,8 +4135,11 @@ pub unsafe extern "C" fn wgpuSurfaceGetCurrentTexture( wgt::SurfaceStatus::Timeout => native::WGPUSurfaceGetCurrentTextureStatus_Timeout, wgt::SurfaceStatus::Outdated => native::WGPUSurfaceGetCurrentTextureStatus_Outdated, wgt::SurfaceStatus::Lost => native::WGPUSurfaceGetCurrentTextureStatus_Lost, - // TODO add some logs to provide more context - wgt::SurfaceStatus::Unknown => native::WGPUSurfaceGetCurrentTextureStatus_Error, + wgt::SurfaceStatus::Occluded => native::WGPUSurfaceGetCurrentTextureStatus_Occluded, + wgt::SurfaceStatus::Validation => { + log::error!("Surface validation error"); + native::WGPUSurfaceGetCurrentTextureStatus_Error + } }; surface_texture.texture = match texture { Some(texture_id) => Arc::into_raw(Arc::new(WGPUTextureImpl { @@ -4351,7 +4352,7 @@ pub unsafe extern "C" fn wgpuTextureGetNativeMetalTexture( .context .texture_as_hal::(texture.id); if let Some(hal_texture) = hal_texture { - return hal_texture.raw_handle().as_ptr().cast(); + return hal_texture.raw_handle() as *const _ as *mut c_void; } std::ptr::null_mut() } @@ -4499,9 +4500,8 @@ pub unsafe extern "C" fn wgpuDeviceCreateShaderModuleSpirV( } #[no_mangle] -pub unsafe extern "C" fn wgpuRenderPassEncoderSetPushConstants( +pub unsafe extern "C" fn wgpuRenderPassEncoderSetImmediates( pass: native::WGPURenderPassEncoder, - stages: native::WGPUShaderStage, offset: u32, size_bytes: u32, data: *const u8, @@ -4509,9 +4509,8 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetPushConstants( let pass = pass.as_ref().expect("invalid render pass"); let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match pass.context.render_pass_set_push_constants( + match pass.context.render_pass_set_immediates( encoder, - from_u64_bits(stages).expect("invalid shader stage"), offset, make_slice(data, size_bytes as usize), ) { @@ -4520,13 +4519,13 @@ pub unsafe extern "C" fn wgpuRenderPassEncoderSetPushConstants( &pass.error_sink, cause, None, - "wgpuRenderPassEncoderSetPushConstants", + "wgpuRenderPassEncoderSetImmediates", ), } } #[no_mangle] -pub unsafe extern "C" fn wgpuComputePassEncoderSetPushConstants( +pub unsafe extern "C" fn wgpuComputePassEncoderSetImmediates( pass: native::WGPUComputePassEncoder, offset: u32, size_bytes: u32, @@ -4535,7 +4534,7 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetPushConstants( let pass = pass.as_ref().expect("invalid compute pass"); let encoder = pass.encoder.as_mut().expect("invalid compute pass encoder"); - match pass.context.compute_pass_set_push_constants( + match pass.context.compute_pass_set_immediates( encoder, offset, make_slice(data, size_bytes as usize), @@ -4545,15 +4544,14 @@ pub unsafe extern "C" fn wgpuComputePassEncoderSetPushConstants( &pass.error_sink, cause, None, - "wgpuComputePassEncoderSetPushConstants", + "wgpuComputePassEncoderSetImmediates", ), } } #[no_mangle] -pub unsafe extern "C" fn wgpuRenderBundleEncoderSetPushConstants( +pub unsafe extern "C" fn wgpuRenderBundleEncoderSetImmediates( bundle: native::WGPURenderBundleEncoder, - stages: native::WGPUShaderStage, offset: u32, size_bytes: u32, data: *const u8, @@ -4563,13 +4561,7 @@ pub unsafe extern "C" fn wgpuRenderBundleEncoderSetPushConstants( let encoder = encoder.expect("invalid render bundle"); let encoder = encoder.as_mut().unwrap(); - bundle_ffi::wgpu_render_bundle_set_push_constants( - encoder, - wgt::ShaderStages::from_bits(stages.try_into().unwrap()).expect("invalid shader stage"), - offset, - size_bytes, - data, - ); + bundle_ffi::wgpu_render_bundle_set_immediates(encoder, offset, size_bytes, data); } #[no_mangle]