Skip to main content

flutter3d_wgpu 1.0.0-rc.2 copy "flutter3d_wgpu: ^1.0.0-rc.2" to clipboard
flutter3d_wgpu: ^1.0.0-rc.2 copied to clipboard

The compute sidecar for flutter3d: a compute-only GraphicsDevice over wgpu-native through dart:ffi, so compute steps run on the GPU when the drawing device has none.

flutter3d_wgpu #

The compute sidecar of flutter3d: a GraphicsDevice that computes and draws nothing, over wgpu-native through dart:ffi.

A frame's compute step runs where the frame can run it. The device that draws comes first, when it has compute (WebGPU does; Impeller will when flutter_gpu has compute pipelines). This package is second: a GPU beside the drawing device, on every native target. The CPU is last, through flutter3d_cpu. The order is the hardware layer's (FrameCompute in flutter3d_hardware), and nothing above it chooses: a frame-graph ComputeStep in flutter3d_core is told where it landed.

import 'package:flutter3d_cpu/flutter3d_cpu.dart';
import 'package:flutter3d_hardware/flutter3d_hardware.dart';
import 'package:flutter3d_wgpu/flutter3d_wgpu.dart';

final registry = DeviceRegistry<Object>();
registerWgpuSidecar(registry); // the sidecar
registerCpuBackend(registry); // the CPU, and the fallback backend
final device = await registry.open(width: 1280, height: 720);
// Frames drawn on `device` now compute on it, then the sidecar, then the
// CPU: a renderer's addComputeStep and addWorkload place there.

The same kernels, the same bytes #

A kernel is written once, in the kernel language (kernel <N>; a material's compute block is lowered to it), and travels in a shader bundle's kernel section. The sidecar loads it as WebGPU does: translated to WGSL by flutter3d_shaders, then compiled by wgpu. The four kernels of the conformance suite (a prefix sum, a particle step, a skinning pass and a blur from a texture into a storage texture) give the bytes the CPU gives on it; test/sidecar_test.dart runs them against the device.

That holds because the WGSL rounds every f32 sum, difference and product where the source rounds it. Metal's compiler fuses a multiply into the add beside it and reorders sums, and before the rounding the particle step came out one ulp off in eight values of sixteen hundred.

Getting what it computed to the screen #

SharedBuffer and SharedTexture in flutter3d_hardware hand the sidecar's output to the drawing device. Today they copy through host memory: flutter_gpu cannot make a texture over a native handle, so Impeller refuses the import, and a demand for zero copy is a SharingException that says which half is missing. On Metal the sidecar can already give its half: WgpuSidecar.metalTextureOf returns the MTLTexture behind a texture it made.

Building #

The build hook fetches the pinned wgpu-native release for the target, checks its sha256, and links the static library into f3d_wgpu, the small C surface in csrc/. The fetch is tool/hook/wgpu_native.dart, which flutter3d_physics_native keeps a copy of (a structure rule holds the two to the same bytes), so both link the same release. What it costs: f3d_wgpu, with wgpu-native in it, is about 11 MB (macOS arm64, 2026-10-13), and a download at the first build. Without a release for the target, or without a network, the hook says so and builds nothing; WgpuSidecar.open then refuses with the reason and the frame computes on the CPU. In the browser there is no sidecar: WebGPU computes for itself.

0
likes
140
points
124
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

The compute sidecar for flutter3d: a compute-only GraphicsDevice over wgpu-native through dart:ffi, so compute steps run on the GPU when the drawing device has none.

Topics

#gpu #compute #ffi #graphics

License

MIT (license)

Dependencies

archive, code_assets, crypto, ffi, flutter3d_foundation, flutter3d_hardware, flutter3d_shaders, hooks, logging, native_toolchain_c

More

Packages that depend on flutter3d_wgpu