Skip to content

Releases: gogpu/wgpu

v0.30.30 — memory leak fix: validation maps pinned resources per frame

Choose a tag to compare

@kolkov kolkov released this 31 Jul 04:59
8eb08aa

Fixed

  • Memory leak: validation maps pinned every resource per frameSetBindGroup copied every bound buffer/texture into encoder maps per draw call. Maps never cleared after Submit/Release, pinning BindGroup objects indefinitely. Now tracks bind groups only; validation walks boundBuffers/boundTextures transitively. Contributor: @samyfodil (#291)

  • Validation error precedence — buffer/texture errors now deterministically beat bind group errors regardless of map iteration order. Matches Rust wgpu ordering.

v0.30.29 — hotfix: Queue.LastSubmissionIndex deadlock (atomic)

Choose a tag to compare

@kolkov kolkov released this 30 Jul 12:17
92742e6

Hotfix for v0.30.28 deadlock: Submit→Triage→onZero→LastSubmissionIndex→Queue.mu. Changed lastSubmissionIndex from mutex-protected uint64 to atomic.Uint64.

v0.30.28 — unified resource lifecycle (ADR-056, Rust wgpu parity)

Choose a tag to compare

@kolkov kolkov released this 30 Jul 12:00
146bc28

Fixed

  • Resource lifecycle: BindGroup/Pipeline Release() bypasses ref-counting
    Release() called dq.Defer(lastSubmissionIndex) directly, ignoring the
    ResourceRef ref-counting system. On shared encoder path, this caused
    use-after-free: HAL resource destroyed while GPU still processing commands.
    Now Release() calls ref.Drop() — HAL destruction deferred until ALL
    refs (user + GPU) are dropped. Matches Rust wgpu Arc<BindGroup> pattern.
    Applied to: BindGroup, RenderPipeline, ComputePipeline. (#287)

  • DestroyQueue deadlock: Triage → onZero → Defer re-entry
    Triage() held mutex while executing callbacks. When onZero fired and
    called Defer(), it tried to acquire the same mutex → deadlock. Now
    callbacks execute outside the lock. Same fix applied to FlushAll().

Tests

  • 6 new lifecycle tests: refcount transitions, Release-before-Submit,
    Release-without-Clone, mixed-resource TrackedSubmission, buffer binding scenario

v0.30.27 — GLES 3D rendering: MappedAtCreation flush + depth fixes

Choose a tag to compare

@kolkov kolkov released this 30 Jul 08:37
d58070d

Fixed

  • GLES: MappedAtCreation buffer data silently discarded on Unmap
    UnmapBuffer only flushed shadow data to GL when BufferUsageMapWrite was set.
    Per WebGPU spec, MappedAtCreation does NOT require MapWrite usage. Buffers
    with Uniform|CopyDst + MappedAtCreation (the standard g3d pattern) had their
    data thrown away — zero MVP matrices, zero vertices, zero indices. Root cause of
    invisible 3D geometry on GLES. (#284)

  • GLES: depth/stencil attachment point chosen by format
    GL_DEPTH_ATTACHMENT for depth-only formats, GL_DEPTH_STENCIL_ATTACHMENT for
    combined. Wrong attachment point caused FBO incomplete (0x506). Rust wgpu-hal
    parity (command.rs:577-580). (#284)

  • GLES: depth clear masked by stale pipeline stateClearDepthCommand now
    calls glDepthMask(true) + glClearDepth(value) before glClear. Prevents
    stale DepthMask(false) from prior pipeline silently masking depth clear. (#284)

  • GLES: viewport depth range ignoredSetViewportCommand now calls
    glDepthRange(minDepth, maxDepth). Was ignoring depth range fields entirely.
    Rust wgpu-hal parity (queue.rs:1295-1296). (#284)

Added

  • gl.Context.ClearDepth() and gl.Context.DepthRange() wrapper methods for
    both Windows (syscall, double) and Linux (goffi, float32 for GLES).

Changed

  • deps: gpucontext v0.22.0 → v0.23.0

v0.30.26 — GLES depth/stencil fix for surface render pass

Choose a tag to compare

@kolkov kolkov released this 30 Jul 07:28
49c7c8f

Fixed

  • GLES: depth/stencil not attached to swapchain FBO on surface render pass
    setupSurfaceTarget() had an early return that skipped depth/stencil attachment.
    3D content with depth testing was invisible on GLES while Vulkan and DX12 worked
    correctly. Now attaches depth/stencil to the swapchain FBO via
    AttachDepthStencilToFBOCommand. Matches Rust wgpu-hal GLES begin_render_pass
    which uses the same draw_fbo path for both surface and offscreen targets. (#284)

Changed

  • deps: gpucontext v0.22.0 → v0.23.0

v0.30.25 — deps gpucontext v0.22.0

Choose a tag to compare

@kolkov kolkov released this 29 Jul 16:11
e1637d5

[0.30.25] - 2026-07-29

Changed

  • deps: gpucontext v0.21.1 → v0.22.0 — FontSmoothing type + coordinate space docs (gogpu#396, gogpu#398)

v0.30.24 — Surface API contract + Metal -race fix

Choose a tag to compare

@kolkov kolkov released this 29 Jul 15:21
0d02699

Fixed

  • Browser/Rust Surface missing methodsPresentPixels, WritePixels,
    SetPrepareFrame, and SetPresentsWithTransaction now exist on all backends.
    Missing methods return clear errors or no-op, matching ADR-047 (unified public
    API). Fixes WASM build failure introduced by gogpu PR #370. (#281)

  • Metal checkptr abort under -race — ObjC block callback trampolines used
    unsafe.Pointer(blockPtr + 32) which violates Go's pointer provenance rules.
    Replaced with unsafe.Add(unsafe.Pointer(blockPtr), 32) (Go 1.17+) at all 4
    block callback locations. go test -race now works on Metal compute. (#280)

Added

  • Compile-time Surface API contract — anonymous interface assertion
    (var _ interface{...} = (*Surface)(nil)) in each backend file enforces that
    all public methods exist at compile time (ADR-047 enforcement).

  • CI cross-compile jobGOOS=js GOARCH=wasm (browser) and -tags=rust
    (Rust FFI) builds added to CI pipeline. Missing Surface methods now fail the
    PR, not the downstream consumer.

CI

  • Android SDK setup: use pre-installed SDK instead of third-party action (v3/v4 both crash on Preview license)
  • goffi version check updated v0.6.1 → v0.6.2 in Android preview script
  • DX12 command.go formatting fixed

v0.30.23

Choose a tag to compare

@kolkov kolkov released this 26 Jul 19:11

What's Changed

Fixed

  • Device teardown GPU drain orderingDevice.Release() drains GPU work before destroying staging buffers. Matches Rust wgpu Queue::Drop. (@besmpl #264)
  • Vulkan swapchain fail-closed lifecycle — transactional reconfiguration, capability validation, broken-state tracking. (@besmpl #265)
  • Explicit mock adapter constructioncore.NewInstance no longer fabricates mock adapter. Rust wgpu parity. (@besmpl #266)
  • Surface lifetime ownership — centralized acquisition/teardown with lease system, deterministic release ordering. (@besmpl #269)
  • Vulkan nil pipeline layout guard — HAL rejects nil layouts before Vulkan call. (@besmpl #257)
  • Metal autorelease pool thread pinningLockOSThread prevents goroutine migration. Go 1.14+ preemption fix. (@besmpl #260)
  • Metal texture array copy shapesetArrayLength for 1D/2D arrays instead of setDepth. Rust parity. (@besmpl #261)
  • DX12 submission-ordered state reconciliation — command-local tracking, preamble barriers, depth/stencil planes. (@besmpl #262)
  • nil WritePixels receiverSurface.WritePixels on nil surface returns ErrReleased. (@besmpl #277)
  • Metal storage-mode test fixture — aligned with isAppleGPU policy from v0.30.22. (@besmpl #275)

Added

  • Surface-qualified adapter selectionRequestAdapterWithSurface via vkGetPhysicalDeviceSurfaceSupportKHR. Ahead of Rust wgpu. (@besmpl #267)
  • Typed surface targets (Rust v29 parity)CreateSurfaceFromTarget, CreateSurfaceUnsafe with opaque constructors. (@besmpl #273)
  • Android arm64 Vulkan (guarded preview) — API 29+, Bionic loader via goffi v0.6.1. (@besmpl #268)
  • Fixed-count indirect multi-drawMultiDrawIndirect/MultiDrawIndexedIndirect with overflow-safe arithmetic. 2 improvements over Rust wgpu. (@besmpl #253)
  • Metal ICB optimization — indirect command buffers for large indexed multi-draws. Original optimization beyond Rust. (@besmpl #263)
  • Headless surface readbackHeadlessSurfaceTarget + Surface.ReadPixels() for golden image testing. (@besmpl #276)

Changed

  • Bump naga v0.17.15 → v0.17.16 — MSL 64-bit atomics rejection (@besmpl)
  • Bump goffi v0.6.1 → v0.6.2 — Windows AMD64 float returns fix (@besmpl)
  • Bump webgpu v0.5.3 → v0.5.4 — Android surface, timestamp period, callbacks (@besmpl)
  • DX12 lint cleanup — builtin shadow fix, struct returns, dead code removal
  • CODEOWNERS@besmpl added for Android paths
  • ROADMAP + ARCHITECTURE — updated for 18 merged PRs
  • CONTRIBUTING.md — Smart Coding framework, AI-assisted policy

Full Changelog: v0.30.22...v0.30.23

v0.30.22

Choose a tag to compare

@kolkov kolkov released this 16 Jul 09:06
889fb9a

What's Changed

Fixed

  • Metal MSAA texture storage mode crash on Intel Mac — use MTLGPUFamilyApple1 detection instead of hasUnifiedMemory for texture storage mode selection. Non-Apple GPU family devices (Intel/AMD) now always use MTLStorageModePrivate for textures. Apple Silicon keeps MTLStorageModeShared optimization for single-sample textures. Fixes #271.

Details

Intel integrated GPUs (e.g. Iris Plus 655) report hasUnifiedMemory=true but are NOT Apple GPU family. Metal spec requires MTLStorageModePrivate for multisample textures on non-Apple-family devices. Our previous code used hasUnifiedMemory to select MTLStorageModeShared for all textures, causing SIGABRT on the first frame when creating MSAA render targets.

The fix adds isAppleGPU detection via the existing DeviceSupportsFamily(device, MTLGPUFamilyApple1) infrastructure, which is the correct semantic check for storage mode capability. This preserves our MTLStorageModeShared optimization for single-sample textures on Apple Silicon (better than Rust wgpu-hal, which uses Private for all textures unconditionally).

Thanks to @AnyCPU for the detailed bug report with root cause analysis, patch, and regression test.

Full Changelog: v0.30.21...v0.30.22

v0.30.21

Choose a tag to compare

@kolkov kolkov released this 15 Jul 19:34
f33f9be

What's Changed

Fixed

  • Software CopyTextureToBuffer row stride — row-by-row copy respecting BytesPerRow from BufferLayout. Was flat copy(dst, src) ignoring row alignment, causing progressive row shift.

  • Software configureRasterPipeline blend state — extract blend state from Fragment.Targets[0].Blend into the raster pipeline. Was always BlendDisabled, preventing premultiplied alpha compositing. Added convertBlendState, convertBlendFactor, convertBlendOp.

  • Software readTexel BGRA format — swap R/B channels for BGRA8Unorm / BGRA8UnormSrgb textures. Replaced hardcoded format constants with gputypes imports.

Full Changelog: v0.30.20...v0.30.21