A one-field bug, a billion phantom steps — and the macOS Metal hang is gone.
Today we released OxiGDAL 0.1.5 — a small, targeted fix release that corrects a GPU uniform-buffer layout bug and restores reliable compute-shader execution on macOS Metal.
OxiGDAL remains a Pure Rust geospatial data abstraction library — no C, no C++, no Fortran, no PROJ/GEOS — that compiles to a single static binary or a sub-1 MB WASM bundle. This release does not change that surface; it makes one corner of it solid.
Why 0.1.5 matters
GPU acceleration in OxiGDAL runs through wgpu, and wgpu enforces strict alignment rules for uniform buffers. A subtle mismatch between the Rust-side struct and the WGSL declaration is the classic way to corrupt a compute dispatch — and that is exactly what had crept into the ray-march path.
In oxigdal-gpu, the RayMarchUniforms struct carried a stray _pad1: f32 that shifted every subsequent field by four bytes. The practical consequence was severe: the compute kernel read max_steps as roughly 1.05 × 10⁹ instead of its real value, then looped that many times. On macOS Metal, device.poll(wait_indefinitely) would block forever, and the parity test test_ray_march_gpu_matches_cpu_when_backend_present simply timed out.
Removing the stray padding aligns the WGSL layout with the Rust struct. The kernel now reads the correct step count, finishes promptly, and the previously-hanging GPU/CPU parity test passes in 0.127s.
Technical Deep Dive: layout discipline in wgpu
Uniform buffers in WGSL follow std140-style alignment: fields are padded to specific boundaries, and the Rust-side representation must match byte-for-byte or the shader reads garbage. The failure mode here is instructive:
- A single misplaced
f32of padding offset all following fields by 4 bytes. - A
u32step counter landed on the wrong offset and decoded as a near-u32::MAXvalue. - The kernel’s bounded loop became effectively unbounded — a billion iterations.
- Under
device.poll(wait_indefinitely), the host thread waited on a dispatch that would never realistically return, presenting as an indefinite hang rather than a crash.
The fix is the right kind of fix: delete the offending field so the layouts coincide, and let the existing GPU/CPU parity test prove correctness. With 78 crates and 14,605 passing tests (plus 405 doc tests) in the workspace, this is the test suite catching a real platform-specific defect and confirming the repair.
Getting Started
cargo add oxigdal
The public API is unchanged from 0.1.4 — opening datasets works exactly as before:
use oxigdal::Dataset;
fn main() -> oxigdal::Result<()> {
let dataset = Dataset::open("world.tif")?;
println!("Format : {}", dataset.format());
println!("Size : {}x{}", dataset.width(), dataset.height());
println!("CRS : {}", dataset.crs().name());
Ok(())
}
GPU-accelerated paths live behind the oxigdal-gpu crate; if you were exercising the ray-march kernel on macOS, this is the release that makes it usable.
What’s New in 0.1.5
- GPU ray-march WGSL layout fix (
oxigdal-gpu) — removed the stray_pad1: f32inRayMarchUniformsthat shifted every field by 4 bytes and caused the compute kernel to readmax_steps≈ 1.05 × 10⁹, hangingdevice.poll(wait_indefinitely)indefinitely on macOS Metal. The previously-timing-out parity test now passes in 0.127s.
Tips
- Upgrade if you run GPU code on macOS. This is the only behavioral change in 0.1.5, and it is the difference between a working ray-march kernel and an indefinite hang on Metal.
- Treat uniform layouts as a contract. When a
wgpucompute kernel reads implausible values (a step count nearu32::MAXis a tell), suspect a Rust-struct ↔ WGSL alignment mismatch before anything else. - Lean on the parity tests.
oxigdal-gpuvalidates GPU output against a CPU reference; if you extend the GPU crate, keep adding*_matches_cpu_*tests — they catch exactly this class of bug. - No code changes required elsewhere. Everything else is identical to 0.1.4; this is a safe, drop-in patch upgrade.
This is the foundation
OxiGDAL remains the geospatial layer of the COOLJAPAN Pure Rust ecosystem, built on OxiArc for compression, OxiCode for serialization, SciRS2-Core for numerics, OxiONNX for ML inference, and RS3GW for S3-compatible storage. A focused release like this one is part of the maturity story: real GPU code, exercised by real tests, hardened across platforms.
Repository: https://github.com/cool-japan/oxigdal
Star the repo if you want geospatial GPU compute in Pure Rust that behaves the same on Metal as everywhere else.
Pure Rust cloud-native geospatial is here — fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ May 22, 2026