juj / wasm_webgpu

System headers for interfacing WebGPU from C programs compiled via Emscripten to WebAssembly

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Should the Emscripten library_webgpu be used instead?

brendan-duncan opened this issue · comments

Copying it from the master Emscripten branch to get the latest binding? Google was a little concerned about having multiple bindings. I started using this version at the beginning because it's convenient to be able to modify it. I haven't studied the two in comparison to see what the advantages are otherwise. The Emscripten library_webgpu version does seem to be lagging behind the current spec, it doesn't appear to have the GPUPresentationContext functions and still has the swap chain.

commented

We have been discussing this bindings project with Google before. The current Emscripten bindings are a bit verbose, not geared as aggressively towards tiny code size, performance and minimal generated garbage in mind as I would have liked, hence starting this one.

That is not to say that the upstream bindings would be somehow bad - just that I did not find using it preferable. That could be due to having grown quite particular to how the existing WebGL bindings layer should look for best results to my liking, and expecting the same for my WebGPU bindings library.

The major design difference is that upstream Emscripten bindings library utilizes ref-counting, so C/C++ side needs to do more manual releasing of object refcounts in certain cases. This bindings layer uses traditional WebGL/OpenGL-style delete functions without reference counters, and aims to minimize the need to manually remember to delete different objects with explicit API calls. (hence e.g. the submit_one_and_destroy() style of API)

Both bindings have a current drawback that they lack test cases, hence the outdatedness of upstream Emscripten library showing, and also the silly typos/mistakes like you are seeing in this library. (great work reporting these!)

The upstream Emscripten bindings layer has a goal to be compatible with native Dawn API, so that one can co-target Dawn and WebGPU from the same codebase. This bindings library does not have that goal. Also the upstream bindings layer provides a C++ class-based API, which this library does not pursue.

Last time I looked, the Emscripten bindings library did not have completed the context initialization sequence, but expected a preinitialized Module['preinitializedWebGPUDevice'] WebGPU device to have been created via manual JS code. So there are currently no "self-contained" C examples to use the upstream Emscripten bindings layer.

Also both libraries have different sets of missing items/TODOs atm.

Also since this bindings library does not aim for Dawn native compatibility, I have taken liberties with the API design in places to ease/improve marshalling. Beyond the non-refcounting aspect and functions such as wgpu_queue_submit_one_and_destroy(), the examples that come to mind so far:

  • struct ABI layout differs from the WebIDL in certain places to simplify padding and 32-bit wide reads from JS, and to help polymorphed descriptor reads,
  • 64-bit integers are not used in some function calls, but doubles are used instead, supporting only up to 2^53 large integers, (which should be plenty enough - BigInts could be used in the future)
  • some descriptor structs are removed, and instead the functions take the descriptor args flattened as function parameters, see e.g. wgpu_queue_write_texture() and wgpu_queue_copy_external_image_to_texture(). This is done to simplify marshalling, though could come back to bite, but not much of an issue atm since backwards compatibility is not yet a thing. (we'll see how these live)
  • accessing buffer mappings is done via a custom API to avoid memcpy width problems and allow windowed reads and writes. See the vertex_buffer example, and wgpu_buffer_get_mapped_range(), wgpu_buffer_read_mapped_range() and wgpu_buffer_write_mapped_range() functions. That populates a several MB vertex buffer by having just a few hundred KBs of Wasm heap size.
  • currently, a random set of custom API functions, like wgpu_enum_to_string(), wgpu_get_num_live_objects(), wgpu_object_destroy(), wgpu_is_valid_object(), wgpu_is_*() are provided.

I'll close this issue, since the intent here is not for the upstream Emscripten bindings layer to replace this bindings layer. At the moment the intent is neither to have this bindings library replace the upstream Emscripten bindings layer (mainly because of the Dawn incompatibility, but also because I don't know if I will have the cycles to step up to own maintainership if I did push this upstream), although that thought was briefly entertained in one call with Google.