feat(webgpu): WebGPU backend via Dawn, rebased onto v1.75.0 - #242
Open
nmfisher wants to merge 23 commits into
Open
feat(webgpu): WebGPU backend via Dawn, rebased onto v1.75.0#242nmfisher wants to merge 23 commits into
nmfisher wants to merge 23 commits into
Conversation
Materials are now built as two separate variants: - _native: OpenGL + Metal + Vulkan shaders (smaller for standard builds) - _webgpu: WGSL shaders only (smaller for WebGPU builds) Both variants use identical C symbol names (IMAGE_PACKAGE, etc.) so runtime code doesn't change. Only one .c is compiled by the build hook based on the webgpu user-define. Forwarding headers dispatch via Build hook has a fallback to unsuffixed .c files so existing materials continue to work until make materials is re-run with matc. Changes: - materials/build.sh: runs matc twice per material (native + webgpu), generates suffixed .c/.h files and forwarding headers - hook/build.dart: selects _native or _webgpu suffix with fallback - Removed unused .S/.apple.S/.bin files (build hook uses .c files) NOTE: make materials requires FILAMENT_PATH with matc built with FILAMENT_SUPPORTS_WEBGPU=ON. Until then, existing unsuffixed materials are used via the build hook fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebuilt all materials using matc with FILAMENT_SUPPORTS_WEBGPU=ON. Each material now has two variants: - _native: OpenGL + Metal + Vulkan (68KB avg per material) - _webgpu: WGSL only (19KB avg per material) Fixed build.sh to use same .filamat filename for both variants so resgen produces identical C symbol names (IMAGE_IMAGE_DATA etc.) in both headers. WebGPU test results with new WGSL materials: - quad_tests: PASS (was crashing: Image material not built for WGSL) - overlay_tests: 9/9 PASS (was crashing: Grid material not built for WGSL) - wireframe: PASS (was crashing: Wireframe material not built for WGSL) - depth_tests: still crashes (LinearDepth uses gl_FragCoord.z, a GLSL-specific built-in not supported in WGSL transpilation) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce compile-time backend selection with four material variants: _native — OpenGL + Metal + Vulkan (GLSL, SPIR-V, MSL) _webgpu — WebGPU only (WGSL) _web_webgl — WebGL2 only (GLSL), smallest web variant _web_combined — WebGL2 + WebGPU (GLSL + WGSL), runtime selection Downstream developers select via pubspec.yaml: hooks.user_defines.thermion_dart.backend: native|webgpu|webgl2|hybrid Changes: - build.sh: produces 4 variants per material, refactored with build_variant() - build.dart: 'backend' user define replaces legacy 'webgpu: true/false' (legacy still works for backward compat). Maps to material suffix and THERMION_MATERIAL_* define. - Web CMakeLists: THERMION_MATERIAL_VARIANT cmake variable selects variant. Explicit file list replaces broken *.c glob that caused duplicate symbols. - macOS test CMakeLists: updated to use _native suffixed files. - All forwarding headers: 4-way #ifdef dispatch with #error fallback. - capture_uv: split into all 4 variants (was previously unsplit). - Removed dead #include "material/outline.h" from TMaterialInstance.cpp. - Removed stale .S/.bin assembly files and outline.c/outline.h. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Users can now pick Backend.WEBGPU on web; WebGL2 remains the default. Selection on Flutter is via WebOptions(backend: ...); a WebGpu.isSupported() helper exposes navigator.gpu detection so callers can soft-fall-back without round-tripping into wasm. Native: - Insert BACKEND_WEBGPU=4 in TBackend, bump NOOP to 5 to align with filament::backend::Backend (which added WEBGPU=4 upstream — Thermion's NOOP was silently mapping to Filament's WEBGPU). - ThermionWebGPUPlatform subclasses Filament's abstract WebGPUPlatform, binding wgpu::Surface to #thermion_canvas. (Filament doesn't ship an Emscripten concrete subclass — only Linux/Apple/Windows/Android.) - Engine_create branches on backend: WEBGPU -> WebGPU platform; else existing WebGL2 path. - CMakeLists adds -sUSE_WEBGPU=1. Materials: matc now invoked with -a webgpu in addition to opengl/metal/ vulkan, so .filamat blobs carry WebGPU shader variants. Examples: js_wasm and Flutter quickstart accept ?backend=webgpu URL toggle, with auto-fallback to WebGL2 if navigator.gpu is missing. Requires a Filament prebuilt built with FILAMENT_SUPPORTS_WEBGPU=ON; the current pinned v1.69.1 web zip will need rebuilding. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the C++/Dart plumbing for Backend.WEBGPU on desktop & Android, gated
behind a userDefine so default builds remain unaffected. Intended for
local validation of the WebGPU path on a platform where the developer
controls the Filament build; production native builds should stay on
Metal/Vulkan/OpenGL.
- TEngine.cpp: when THERMION_SUPPORTS_WEBGPU is defined and the caller
passes BACKEND_WEBGPU with a null platform, auto-construct the
platform-specific WebGPUPlatform subclass (Apple/Linux/Windows/Android).
Headers gated on the same define so default builds don't pull in
webgpu_cpp.h transitively.
- hook/build.dart: new `webgpu` userDefine gates THERMION_SUPPORTS_WEBGPU
and reserves a slot for the Dawn lib list (left as a TODO until the
exact lib names can be enumerated from a built Filament).
- native plugin: Backend.WEBGPU is now an accepted value in the
supported-backends switch; no platform restriction since Dawn
translates to the native graphics API on every supported OS.
Consumer opts in via pubspec:
hooks:
user_defines:
thermion_dart:
webgpu: true
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extends scripts/build_macos.sh with three orthogonal flags so the same script can fetch + build + ship a Filament artifact with the Dawn-backed WebGPU backend. - FILAMENT_VERSION=latest: resolves the newest v*.* tag from github.com/google/filament via `git ls-remote --sort=-version:refname`. - --webgpu: injects -DFILAMENT_SUPPORTS_WEBGPU=ON into the cmake commands alongside the existing -DFILAMENT_SKIP_SAMPLES=ON patch, and after the build copies all Dawn static libs (recursively, since Dawn produces many granular targets) plus the generated webgpu/webgpu_cpp.h header into the target dir. - --upload: pipes the resulting zip(s) through scripts/upload_r2.sh after the build completes. Existing invocations (no new flags) are unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lets the manual workflow_dispatch trigger a WebGPU-enabled macOS build against any branch (incl. claude/webgpu) without merging first. - New `webgpu` boolean input (default false) appends `--webgpu` to the build_macos.sh invocation in the build-macos job. - The setup job's Read Filament version step now resolves FILAMENT_VERSION=latest to a concrete v*.* tag via `git ls-remote --sort=-version:refname` before the per-platform jobs do their depth-1 clone (which can't handle the literal "latest"). R2 upload continues to use the existing `aws s3 cp` step gated on `upload_to_r2`; the build script's own --upload flag is ignored here. Other platforms (ios/android/linux/windows/web) are unchanged — their build_*.sh scripts don't currently honour --webgpu. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…l R2 keys A --webgpu run was about to upload to the exact same S3 key as the canonical Filament build (e.g. filament-v1.69.1-macos-release.zip), silently swapping in Dawn-enabled libs for every downstream consumer fetching via hook/build.dart. Now the build_macos.sh script and the build-macos workflow job both suffix the output zip with "-webgpu" whenever the flag is on: filament-<version>-macos-release-webgpu.zip The canonical key is untouched and the WebGPU artifact sits beside it. The workflow computes ZIP_SUFFIX once via GITHUB_ENV so the artifact path, artifact name, and S3 key all stay in sync. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors the macOS WebGPU plumbing for the Linux build so the Filament artifact for Linux can also be produced with Dawn/WebGPU linked in. Useful for headless testing inside a Docker container. - build_linux.sh: --webgpu injects -DFILAMENT_SUPPORTS_WEBGPU=ON into Filament's build.sh, recurses Dawn's build tree to collect static libs and generated webgpu headers, and suffixes the resulting zip with -webgpu so it never overwrites the canonical Linux artifact on R2. - build_linux.sh: --upload pipes the resulting zip(s) through upload_r2.sh after a successful build. - build_linux.sh: FILAMENT_VERSION=latest now resolves to the newest v*.* tag from github.com/google/filament. - build-filament.yml: the existing webgpu workflow_dispatch input now also drives the Linux job — compute ZIP_SUFFIX, pass --webgpu through, and suffix artifact paths, artifact names, and S3 destinations.
Dawn's X11 backend (DAWN_USE_X11) includes <X11/Xlib-xcb.h> via dawn/common/xlib_with_undefs.h, which lives in libx11-xcb-dev, not the plain libx11-dev we were installing. Add libx11-xcb-dev plus libxcb1-dev to the Linux build job's apt-get list so the Dawn-linked Filament build gets past the dawn_native compile. Fixes the failure on the first Build Filament(linux, webgpu) run: third_party/dawn/src/dawn/common/xlib_with_undefs.h:44:10: fatal error: 'X11/Xlib-xcb.h' file not found
Dawn's X11/XCB backend pulls in headers from a sprawl of xcb-* extension packages (dri3, present, randr, sync, shape, xfixes, image, render, keysyms, util, xkb, shm-fence, xkbcommon). Install them all up front rather than discovering each missing header on a fresh CI run.
- TestHelper: add optional backend parameter so tests can select Backend.WEBGPU instead of the platform default (OpenGL on Linux) - TEngine: store WebGPUPlatform* global when WebGPU backend is selected, for future use by Dawn event processing - TRenderer: add explanatory comments about the async readback challenge - capture_tests_webgpu.dart: placeholder test documenting that Filament v1.71.5's WebGPU driver does NOT implement readPixels (confirmed via symbol analysis — WebGPUDriver has readTextureToBuffer but not readPixels; the base class no-op is used instead) The WebGPU smoke test (engine creation + teardown) continues to pass. Capture/readback tests will be re-enabled when Filament adds readPixels support for the WebGPU backend. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Filament v1.71.5 did not implement readPixels for the WebGPU backend. The latest main branch includes a full readPixels implementation with format conversion, staging buffers, and async buffer mapping. - Update filament.version to point at main branch - Sync all public headers from latest Filament source - New: filament/FrameHistoryStream.h - Updated: 38 header files across backend/, filament/, and libs - Preserved manually-added dirs: bluevk/, vulkan/, webgpu/, dawn/, utils/android/, utils/linux/, etc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ing bug WebGPU readPixels now works with Filament built from main (post-v1.71.5). The ConcreteDispatcher<WebGPUDriver>::readPixels symbol is compiled in (the method is inlined via UTILS_ALWAYS_INLINE). Key findings: - The headless swapchain uses RGBA8Unorm format - Requesting FLOAT readback triggers a format-conversion blit in Filament's WebGPUBlitter, which fails because it enables blending on RGBA32Float (a non-blendable format in WebGPU/Dawn) - UBYTE readback matches the swapchain format and avoids the blit entirely Changes: - Add WebGPU readPixels capture tests (UBYTE, both direct and via FLOAT-to-UBYTE workaround) - Add backend getter to FilamentApp/FFIFilamentApp for backend-aware workarounds - Add WebGPU workaround in capture(): auto-downgrade FLOAT to UBYTE when reading from swapchain (no render target) - Sync Filament headers from main (bluevk, utils) for UTILS_GUARDED_BY and other new macros needed by Platform.h - Document upstream Filament blitter issue in docs/upstream.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test helper's capture() method now mirrors the WebGPU workaround in FFIFilamentApp.capture() — when the backend is WebGPU and FLOAT readback is requested from the swapchain, it uses UBYTE for the PNG writer's isFloat check so the buffer is interpreted correctly. This fixes all asset_tests running against the WebGPU backend (5/5 pass). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Runs asset add/remove/destroy/bounding-box tests against the WebGPU backend (Dawn + lavapipe). Co-Authored-By: Claude <noreply@anthropic.com>
Nothing references this tree. Build scripts no longer copy Filament headers into a committed directory (see comments in scripts/build_*.sh); consumers source them from the version-matched R2 artifact at build time via thermion_dart/hook/build.dart, which adds only native/include and the artifact include root to the include path. Co-Authored-By: Claude <noreply@anthropic.com>
build_linux.sh: add -stdlib=libc++ to CMAKE_CXX_FLAGS for imageio and tinyexr so their static archives use the same C++ stdlib as the rest of the .so. Removes the root cause of the libstdc++/libc++ ABI clash that forced us to skip both libs on Linux. hook/build.dart: move webgpu detection before getLibDir so the build hook can download the -webgpu suffixed zip from R2 (e.g. filament-v1.71.5-linux-release-webgpu.zip) instead of the canonical artifact. Previously the webgpu build had to be manually staged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…PLES injection The webgpu change (e9605e8) rewrote the build.sh patch sed with double quotes, collapsing the escaped backslashes so sed failed with "unterminated `s' command". The failure was unchecked, so -DFILAMENT_SKIP_SAMPLES=ON was never injected, Filament built the samples, and the debug link failed with multiple-definition errors for stb_image_write symbols (seen on the Linux arm64 CI run 31877482056). Restore the single-quoted form from before the regression, splicing in $CMAKE_INJECT between quoted segments, and fail fast if the patch does not match. Co-Authored-By: Claude <noreply@anthropic.com>
Mirrors the merged PR #243 change from develop. workflow_dispatch runs read .github/workflows/build-filament.yml from the dispatched ref, so the macos-15 bump must be present on asb/webgpu for the re-dispatched macOS Dawn build to pick it up. macos-14's Xcode 15.4 / Clang 15 lacks C++20 parenthesized aggregate initialization (P0960), which Tint requires. Co-Authored-By: Claude <noreply@anthropic.com>
The WebGPU macOS build (run 31880432397) compiled everything but failed zipping the debug artifact: 'zip I/O error - No space left on device'. Dawn debug artifacts are huge and the stock macos-15 image leaves too little free disk. jlumbroso/free-disk-space is Ubuntu-only (apt-based), so remove the large preinstalled toolchains by hand before the build: extra Xcode versions (keeping the selected one), Android SDK/NDK, CoreSimulator runtimes, dotnet, ghcup and boost. Typically frees 30+ GB. Co-Authored-By: Claude <noreply@anthropic.com>
…terials regen build_linux.sh and build_macos.sh now copy the built matc and resgen into the -webgpu zips (bin/matc, bin/resgen) so the R2 artifacts carry a WebGPU-capable toolchain. The official Filament release matc is built without FILAMENT_SUPPORTS_WEBGPU and cannot compile -a webgpu (WGSL) material variants. regenerate-materials.sh downloads bin/matc + bin/resgen from the webgpu-suffixed R2 zip (filament-<tag>-linux-release-webgpu.zip) instead of the release tarball, caches them per version under a distinct key, and smoke-tests that the cached matc accepts -a webgpu before regenerating. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebases the WebGPU/Dawn backend work onto
filament-v1.75.0(22 commits).Highlights:
BACKEND_WEBGPU,Thermion_createWebGPUPlatform)_native/_webgpusplits, WGSL support) —feat(materials)seriesthermion_dart/test/_webgpu_asset_tests.dart)Verification:
flutter analyze— 0 errors inthermion_dart,thermion_flutter, and the quickstart example.Caveat: the branch's material
.filamatblobs were built against an older Filament — regenerate materials (make materials/ CI regen workflow) before any golden-image comparison.