Skip to content

fix: add writable mapped-range API across backends - #318

Merged
kolkov merged 1 commit into
gogpu:mainfrom
tarmo888:feat/mapped-range-write-api
Aug 18, 2026
Merged

fix: add writable mapped-range API across backends#318
kolkov merged 1 commit into
gogpu:mainfrom
tarmo888:feat/mapped-range-write-api

Conversation

@tarmo888

Copy link
Copy Markdown
Contributor

Summary

Add a common writable mapped-range API to the native wgpu backend:

BytesMut() []byte
Flush() error

The browser and Rust backends already expose equivalent behavior. This change brings the native backend into API parity so higher-level libraries such as g3d can write mapped buffer data without build-tag-specific code.

Motivation

MappedRange.Bytes() is currently suitable for reading, but higher-level code that writes mapped buffer contents needs an explicit writable-range API.

The browser backend uses a Go-side staging slice for mapped writes and requires Flush() to copy modified data back to the JavaScript ArrayBuffer. The Rust backend exposes a direct writable mapping. Native mappings also expose direct writable memory.

Without a common API, consumers need platform-specific implementations for the same geometry or buffer upload code.

Changes

  • Added MappedRange.BytesMut() to the native backend.
  • Added MappedRange.Flush() to the native backend.
  • Implemented native BytesMut() as an alias of Bytes().
  • Implemented native Flush() as a no-op because native mappings are directly device-visible.
  • Added a regression test

Related

This change is a prerequisite for the corresponding gogpu/g3d update that switches geometry uploads to the common BytesMut() and Flush() API.

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kolkov kolkov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean PR — fills the native backend gap for BytesMut()/Flush() that browser and Rust backends already have. CI 16/16 pass.

Implementation is correct: native BytesMut() = alias of Bytes(), Flush() = no-op. This matches the Rust backend exactly (mapped_range_rust.go uses the same pattern).

Test follows existing conventions (newDevice + requireHAL + MappedAtCreation).

Design note (non-blocking, for awareness)

Flush() as no-op is correct for DX12, Metal, GLES, Software, and Noop — all return IsCoherent: true from MapBuffer. Vulkan CAN return IsCoherent: false for non-coherent memory types, where CPU writes aren't GPU-visible without vkFlushMappedMemoryRanges. However, this is a pre-existing gap — MappedRange doesn't store the coherency flag, and Bytes() already allows writes with no flush mechanism. The Vulkan UnmapBuffer handles the flush. A proper Flush() for non-coherent Vulkan would need plumbing IsCoherent into MappedRange — that's a separate enhancement.

LGTM.

@kolkov kolkov added type: enhancement Improve existing feature effort: 1 Trivial, < 1 hour community Community contribution or discussion labels Aug 18, 2026
@kolkov
kolkov merged commit dece132 into gogpu:main Aug 18, 2026
15 checks passed
@kolkov kolkov mentioned this pull request Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Community contribution or discussion effort: 1 Trivial, < 1 hour type: enhancement Improve existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants