-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
TLDR
- Can we guarantee a certain minimal alignment when mapping buffers ?
- What would that alignment guarantee be?
- what about
queue.write_buffer_with
- Let's at least document what alignment is guaranteed (or the absence of guarantees)
The long version
The question came up on matrix
when a user maps a buffer, it can bu tempting to cast the byte slice into a slice of whatever it is they are filling the buffer with and then copy into that typed slice. Doing that requires that the mapped slice have the minimum alignment of the type in question. If wgpu were to guarantee a minimum alignment, it would make this pattern easier to get right.
On the web I don't expect this to matter because webgpu buffers are copied to and from typed arrays. The runtime only needs to memcpy bytes around.
I don't see much in the way of documentation or specification about that the alignment guarantees of mapped buffers.
In backends that use a memory allocator like vulkan, we can pass the alignment as a parameter of the allocation request (example) so it would be very easy to set the minimum alignment to some value.
In other backends it might be up to the driver. The various specs I looked at are better at documenting alignment requirements that users must abide to when writing data than alignment guarantees that the drivers must uphold when mapping.
Can wgpu provide alignment guarantees in mapAsync?
Per backend:
- vulkan: easy via the allocator
- metal ?
- On unified memory architectures I'm pretty sure we get the same alignment as the GPU needs which is much larger than what we need. It would be good to get some confirmation.
- At the very least, on all architecture, 16 bytes alignment is guaranteed
- dx12: 16 bytes alignment guaranteed
- The doc for Map does not say anything unlike D3D11's equivalent doc. Connor confirmed that the 16 bytes guarantee applies to dx12 (asked upstream on the dx12 discord).
- Can easily guarantee larger alignments using the allocator.
- GL ?
- ARB_map_buffer_alignment gives at least 64 bytes. See support matrix on gpuinfo.org
- dx11 ?
- D3D_FEATURE_LEVEL_10_0 and later: 16 bytes alignment guaranteed doc
- earlier than D3D_FEATURE_LEVEL_10_0: only 4 bytes alignment guaranteed
- wasm ?
- No alignment guarantees currently, hopefully we can provide some.
If we can what would a good minimum alignment be?
Buffers are not supposed to be small, so I would go as far as give a whole 64 bytes of alignment. That's quite big but not that much compared to a typical buffer size, and in some rare but real situations it's nice to know how data fits into L1 cache lines.
At a minimum, guaranteeing 16 bytes would allow people to read or write common simd types with peace of mind.
The case of queue.write_buffer_with
Since this uses a simple bump allocation, it should be easy to provide alignment guarantees. Should we? How much?