Browse / github.com/storytold/craft-launcher / patch
Proposal: support OCLP Macs with a wgpu compatibility fork
Proposal: support OCLP Macs with a wgpu compatibility fork Related to #38 and #884. ## Summary Proposes an ArtCraft-owned wgpu compatibility fork for OCLP Macs. Both reports show legacy Metal compilers rejecting `metal3.2`; #38 also includes subsequent Intel compute-pipeline failures. The fork addresses both failure classes. ## What changed - Pin wgpu 30.0.1 to [a release-based backport](https://github.com/ITJamie/wgpu-fork/tree/codex/metal-msl-intel-v30.0.1) of gfx-rs/wgpu#10725 and gfx-rs/wgpu#10731. - Restore default internal indirect-call validation on Intel Macs. - Document adoption as `storytold/wgpu`, including the immutable commit pin and
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- ITJamie (imported from pull request #917, open)
- Base
7aafad661a11594a70ae949471d481f30d8fe64a- Size
- +123 −72 in 6 files
- Review
- pending
- Shared
- 2026-10-28
- Id
085247d4edb3a91bf610322c
How it went
No other operator has reported using it yet.
Diff
raw · Cargo.lock Cargo.toml README.md apps/artcraft-launcher/src/main.rs crates/native/src/install.rs docs/oclp-wgpu-fork.md
@@ -2846,8 +2846,7 @@ dependencies = [ [[package]] name = "naga" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "a616d2fb8c89516ac2723a581f69d6c18576046bed761bd6b305e5618e6ae130"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "arrayvec", "bit-set",@@ -2872,8 +2871,7 @@ dependencies = [ [[package]] name = "naga-types" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "590afbf58a6f4f62873cd5cff4468061844bafa1cdf399cc954537c22d768d49"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "hashbrown 0.17.1", "indexmap",@@ -5404,8 +5402,7 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "527ccdf43dd5b2e8676eed9984ce00e2bbb0a1b85b70c1969dcb6cd2eb55ab9e"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "arrayvec", "bitflags 2.13.2",@@ -5434,8 +5431,7 @@ dependencies = [ [[package]] name = "wgpu-core" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "14c018fce9b6270aa203c2fdd56f3cce996713534bd757e4ea58c8560b121f14"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "arrayvec", "bit-set",@@ -5469,8 +5465,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "061f3d319a40d39d00b1ecc2c33b89fe21d4e6fe01859df3500a3a8ecccd6b68"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "wgpu-hal", ]@@ -5478,8 +5473,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-emscripten" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d98b86cf4abf524a902dd35f18ca6a3f08fc2ae9847c8f10b48e30491b1f0b86"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "wgpu-hal", ]@@ -5487,8 +5481,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-wasm" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d260ca2ca8adc654f513a869bf3cac0b47f5b8d3f87803d6942015f8de597aae"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "wgpu-hal", ]@@ -5496,8 +5489,7 @@ dependencies = [ [[package]] name = "wgpu-core-deps-windows-linux-android" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "7586165fd5f6d881cb9ce4bb71f40d6caab2c0f1837e3fc1d9788a197fb6004f"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "wgpu-hal", ]@@ -5505,8 +5497,7 @@ dependencies = [ [[package]] name = "wgpu-hal" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "b6b7fb58561a792bc237628ba0792e332de418fefe145f13b5ed8201e6d52f58"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "android_system_properties", "arrayvec",@@ -5561,8 +5552,7 @@ dependencies = [ [[package]] name = "wgpu-naga-bridge" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d2f62e73117bb7a62bfd9c5a5841438a823f6566c6442a808ee269d2d055c081"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "naga", "wgpu-types",@@ -5571,8 +5561,7 @@ dependencies = [ [[package]] name = "wgpu-types" version = "30.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "99dad6f1fbdbbdb4c278a6508b059d44688f5cebddf78d005a46a31340269286"+source = "git+https://github.com/ITJamie/wgpu-fork?rev=21c08e23135ba27ed1c6b68177ecc20c0d076dd9#21c08e23135ba27ed1c6b68177ecc20c0d076dd9" dependencies = [ "bitflags 2.13.2", "bytemuck",@@ -65,3 +65,6 @@ eframe = { git = "https://github.com/storytold/egui.git", rev = "6d518fc79968157 egui_demo_lib = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" } egui_inspection = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" } winit = { git = "https://github.com/storytold/winit.git", rev = "a517b3846ee8457d84ee4975110bfda6797c44dc" }++# OCLP Metal fixes; proposed organization-owned fork: docs/oclp-wgpu-fork.md.+wgpu = { git = "https://github.com/ITJamie/wgpu-fork", rev = "21c08e23135ba27ed1c6b68177ecc20c0d076dd9" }@@ -243,6 +243,9 @@ releases (`0.4.0` builds as `0.4.1-dev.<commit time>`), which the launcher offer `ARTCRAFT_LAUNCHER_DOWNLOAD_BASE` is set (loopback addresses only), the launcher asks only the mirror, never GitHub. Only builds with the `local-mirror` feature read it; releases never have it. `cargo xtask local help` lists the options (`--only`, `--no-pull`, `--arch`, …). +The [OCLP wgpu fork proposal](docs/oclp-wgpu-fork.md) describes the pinned Metal+compiler workarounds, hardware checks, and proposed organization ownership.+ New contributors and AI agents: start with [`AGENTS.md`](AGENTS.md). Release packaging lives in [`packaging/`](packaging/) and [`.github/workflows/release.yml`](.github/workflows/release.yml). @@ -323,29 +323,9 @@ fn wgpu_options() -> eframe::WgpuConfiguration { config } -/// Returns wgpu's defaults, except that Intel Macs skip the indirect-call validation shaders-/// ([`skips_indirect_validation`]). #[cfg(target_os = "macos")] fn wgpu_options() -> eframe::WgpuConfiguration {- use eframe::wgpu::InstanceFlags;- let mut config = eframe::WgpuConfiguration::default();- if let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = &mut config.wgpu_setup- && skips_indirect_validation(std::env::consts::OS, cfg!(target_arch = "x86_64"))- {- setup.instance_descriptor.flags = setup.instance_descriptor.flags.difference(InstanceFlags::VALIDATION_INDIRECT_CALL).with_env();- }- config-}--/// wgpu compiles its indirect-call validation shaders inside `request_device`. On old Intel Macs-/// on Big Sur and Monterey (Iris and Iris Pro among them), Metal's compiler fails on them with an-/// internal error, the device is lost and the launcher exits at startup (#344). Intel Macs skip-/// them, and other platforms keep wgpu's default. The launcher issues no indirect draws or-/// dispatches. `WGPU_VALIDATION_INDIRECT_CALL=1` still turns them back on. PhotoCraft does the same-/// (storytold/photocraft#3171).-#[cfg(any(target_os = "macos", test))]-fn skips_indirect_validation(os: &str, intel: bool) -> bool {- os == "macos" && intel+ eframe::WgpuConfiguration::default() } /// Wakes whatever is running the launcher: the window while there is one, the tray loop otherwise.@@ -1117,36 +1097,14 @@ mod tests { assert!(!shell.launcher.closed_to_tray); } - #[test]- fn intel_macs_skip_the_indirect_validation_shaders() {- // Metal's compiler fails on them on Intel Iris Macs, losing the device (#344).- assert!(skips_indirect_validation("macos", true));- // Apple silicon, Windows, Linux and the BSDs keep wgpu's validation.- for (os, intel) in [("macos", false), ("windows", true), ("windows", false), ("linux", true), ("linux", false), ("freebsd", true)] {- assert!(!skips_indirect_validation(os, intel), "{os} intel={intel}");- }- }- #[cfg(target_os = "macos")] #[test]- fn intel_macs_create_the_device_without_indirect_validation() {- use eframe::egui_wgpu::WgpuSetup;- use eframe::wgpu::InstanceFlags;- fn flags(config: eframe::WgpuConfiguration) -> InstanceFlags {- match config.wgpu_setup {- WgpuSetup::CreateNew(setup) => setup.instance_descriptor.flags,- WgpuSetup::Existing(_) => panic!("the launcher creates its own wgpu instance"),- }- }- let launcher = flags(wgpu_options());- if !cfg!(target_arch = "x86_64") {- // Apple silicon keeps wgpu's flags.- assert_eq!(launcher, flags(eframe::WgpuConfiguration::default()));- } else {- // The flag is off unless `WGPU_VALIDATION_INDIRECT_CALL` turns it back on.- let asked = std::env::var_os("WGPU_VALIDATION_INDIRECT_CALL").is_some_and(|v| v != "0");- assert_eq!(launcher.contains(InstanceFlags::VALIDATION_INDIRECT_CALL), asked, "{launcher:?}");- }+ fn macos_keeps_wgpu_indirect_validation_defaults() {+ let eframe::egui_wgpu::WgpuSetup::CreateNew(setup) = wgpu_options().wgpu_setup else {+ panic!("the launcher creates its own wgpu instance");+ };+ let expected = eframe::wgpu::InstanceFlags::default().with_env();+ assert_eq!(setup.instance_descriptor.flags, expected); } #[test]@@ -1222,7 +1222,7 @@ pub mod macos { use artcraft_launcher_core::version::Version; - use super::{CraftApp, InstallSource, Installed, Path, PathBuf, Paths, Release, process, staging_dir, swap_into_place};+ use super::{CraftApp, InstallSource, Installed, Path, PathBuf, Paths, Release, process, swap_into_place}; /// `/Applications` when we can write there, else `~/Applications`. fn applications_dir(existing: Option<&Installed>, destination: Option<&Path>) -> Result<PathBuf, String> {new file mode 100644@@ -0,0 +1,98 @@+# Proposal: an ArtCraft-owned wgpu fork for OCLP Macs++ArtCraft Launcher currently disables wgpu's internal indirect-call validation on+Intel Macs to avoid Metal compiler failures. This proposal uses compiler+workarounds in wgpu instead, restoring the normal validation settings.++## Prototype dependency++The workspace patches `wgpu` to this immutable commit:++- Repository: <https://github.com/ITJamie/wgpu-fork>+- Branch: `codex/metal-msl-intel-v30.0.1`+- Commit: `21c08e23135ba27ed1c6b68177ecc20c0d076dd9`+- Upstream proposals: <https://github.com/gfx-rs/wgpu/pull/10725> and+ <https://github.com/gfx-rs/wgpu/pull/10731>++The release backport is based on upstream tag `v30.0.1`. It probes+compiler-supported Metal Shading Language versions,+works around the Intel workgroup attribute compiler failure using the pipeline+descriptor, and emits runtime-sized storage buffers as element pointers on Intel.+Internal wgpu indirect-call validation and shader bounds checks remain enabled.+The workspace resolves wgpu 30.0.1 from this fork instead of the registry,+preserving the released API used by the existing egui fork. No egui fork change+is needed.++## Proposed organization ownership++A maintainer should create a `storytold/wgpu` fork and preserve the backport+branch and commit above. Creating that repository is an organization decision;+this proposal does not assume it already exists.++After the commit is available in the organization fork, change the patch URL in+`Cargo.toml` to `https://github.com/storytold/wgpu`, retain the reviewed `rev`,+and regenerate `Cargo.lock`. Keep a full commit pin rather than a moving branch.+No launcher-specific changes need to be added to the wgpu fork.++Maintain the fork as a temporary compatibility dependency. Follow both upstream+PRs, review upstream updates, and remove the patch once an upstream release+contains both fixes and the OCLP hardware checks pass against that release.++## Build and hardware validation++```sh+cargo build --locked -p artcraft-launcher+cargo xtask ci+```++Run the desktop binary from a logged-in graphical session. Test both Intel Iris+Pro and AMD Radeon R9 M370X on the OCLP Mac, and check ordinary Apple hardware+before adopting the fork for releases. Confirm that the window renders, resizes,+and reopens from the tray. Building successfully alone does not prove rendering.++```sh+WGPU_BACKEND=metal WGPU_VALIDATION_INDIRECT_CALL=1 \+ MTL_DEBUG_LAYER=0 MTL_SHADER_VALIDATION=0 \+ cargo run --locked -p artcraft-launcher+```++The patched Metal framework on the test OCLP Mac crashes with external Metal API+or shader validation enabled. These diagnostic environment settings disable+those external layers, not wgpu's internal indirect-call validation. They do not+establish that every OCLP configuration is supported. Do not disable validation+globally in production code as a substitute for a compiler workaround.++Use `WGPU_POWER_PREF=low` to prefer Intel Iris Pro and `WGPU_POWER_PREF=high`+to prefer the AMD GPU on the test Mac. Confirm the selected adapter in debug logs.++## Recorded prototype results++On a MacBookPro11,5 with macOS 15.8.1 through OCLP, the locked desktop build+completed. `cargo xtask ci` passed formatting, Clippy, workspace tests, and both+WebAssembly checks. The contributor visually confirmed the launcher UI in both the+high-power and low-power runs; debug logs confirmed Intel Iris Pro selection in+the latter. Both runs kept internal indirect-call validation enabled and used+the external-layer environment settings above. Portable test data was isolated+from the installed launcher's data. These were startup/UI smoke checks, not a+full install/update, resize, or tray lifecycle test.++The debug runs took about 35–45 seconds to reach swapchain creation. Startup+performance remains a limitation of this prototype.++The backport's full wgpu suite on Apple M4 Max ran 1,010 tests: 1,002 passed,+eight failed, and six were skipped. The failures were:++- `subgroup_operations`: an expected-failure mismatch.+- `all_passthrough_shaders_binary`, `all_passthrough_shaders_source`, and+ `metallib_passthrough_shader`: missing DXC or offline Metal tools.+- `binding_array_storage_buffers`, `partial_binding_array_storage_buffers`,+ `validate_capabilities`, and the `Computepass Encoding` benchmark: untriaged+ binding-array/capability failures.++Affected-crate Clippy passed using the release's Rust 1.93 toolchain. The new+MSL controls and compute-workgroup regression tests passed in that full run.+This is not a clean full-suite pass or a claim that the fork is release-ready.++The dependency patch applies to the shared desktop and web dependency graph.+The existing `cargo xtask wasm` check must continue to pass; other desktop+platforms still need their normal CI coverage before merging.