juj/wasm_webgpu

Is there a way to bypass `wgpu_buffer_[read/write]_mapped_range()`?

debevv opened this issue · 1 comments

debevv commented

I looked at the additional wgpu_buffer_read_mapped_range() and wgpu_buffer_write_mapped_range() and to me it looked like they perform a copy of the buffer already living on the CPU side. Is my assumption correct? Is there a way to bypass this additional copy or, as I suppose, this is a limitation of working inside the WASM memory?

juj commented

This is indeed a limitation of Wasm. WebAssembly is only able to deal with a single Memory object that is the Wasm linear memory space. (There does exist a multi-memory proposal, but in that proposal all the additional memories need to be bound at Wasm module instantiation time, so unsuitable for WebGPU)

It would be possible to have a uint32_t wgpu_get_u32/u64/f32/f64(WGpuBuffer mappedBuffer, size_t offset); family of functions that seemingly would allow wasm code to read individual values and so avoid needing to memcpy a buffer range from the mapped typed array into the wasm memory.

However that kind of API would be an order of magnitude slower than a memcpy, since it would incur a Wasm->JS->Wasm boundary call for each u32/f32 element, that kind of boundary transition is somewhat slower than e.g. a virtual function pointer call. So memcpying a large subportion into the wasm memory seems like the most efficient route.

If you are dealing with a large mapped buffer, and don't want to have to allocate equally large block in wasm memory, the idea with the API is to allow reading/writing the data in windows/chunks, so that wasm side can deal with a much smaller allocation, e.g. 1 MB chunk at a time, before flushing it out to the wasm buffer. The vertex_buffer example shows that style of usage.