## Important Notice

Emscripten's WebGPU bindings are in a temporary **breaking-change freeze**.
Bugfixes and small feature additions are still welcome.

Stable headers are being developed in [webgpu-headers](https://github.com/webgpu-native/webgpu-headers)
but will require a number of breaking changes relative to Emscripten's current implementation.
Instead of constantly landing incremental breaking changes in Emscripten, the Dawn project
(native C++ implementation of webgpu.h) has forked Emscripten's bindings to do these incremental
changes, before upstreaming all of the changes at once back into Emscripten.
See [emdawnwebgpu](https://dawn.googlesource.com/dawn/+/refs/heads/main/src/emdawnwebgpu/) for more info.

# WebGPU Bindings

These files, and several snippets of other files, are generated by Dawn
(Chromium's WebGPU library):
- [Generator](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/generator/)
- [Generator input](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/dawn.json)
- [Generator output](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/emscripten-bits/)

The C header is intended to be mostly the same as the "upstream"
[`webgpu.h`](https://github.com/webgpu-native/webgpu-headers/blob/main/webgpu.h),
but both are in flux, and some experimental elements are included and other
native-specific elements are excluded.

The C++ files are **currently** Dawn-specific, but included in Emscripten for
better compatibility with Dawn: it has roughly the same API as Dawn's copy, but
is included here because it is strongly tied to an exact `webgpu.h` revision.

To update these bindings from Dawn:
(TODO: these links are broken because Chromium Code Search is not currently building these generated files.)

1. Copy [`webgpu_enum_class_bitmasks.h`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/dawn/include/webgpu/webgpu_enum_class_bitmasks.h) from Dawn's source to `system/include/webgpu/webgpu_enum_class_bitmasks.h`
1. Build Dawn's `emdawnwebgpu_headers_gen` and `emdawnwebgpu_js_gen` targets (in a gn build of Dawn, or a build of Chromium) - or, use the Chromium Code Search copy of the generated files if no changes are needed
1. Copy the generated [`include`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/src/emdawnwebgpu/include/) files into Emscripten's `system` directory:
    - `system/include/webgpu/webgpu.h`
    - `system/include/webgpu/webgpu_cpp.h`
    - `system/include/webgpu/webgpu_cpp_chained_struct.h`
1. Paste the contents of [`library_webgpu_enum_tables.js`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/src/emdawnwebgpu/library_webgpu_enum_tables.js) over the "Map from enum number to enum string" section of [`library_webgpu.js`](../../../src/library_webgpu.js)
1. Copy the generated [`struct_info_webgpu.json`](https://source.chromium.org/chromium/chromium/src/+/main:out/linux-Debug/gen/third_party/dawn/src/emdawnwebgpu/struct_info_webgpu.json) to [`struct_info_webgpu.json`](../../../src/struct_info_webgpu.json).
1. **Manually update the `globalThis.gpu` compile-time enum tables (AdapterType, BackendType, etc.)**:
    - Inspect the `webgpu.h` diff for changes to the integer values of any enums used here. (It's not necessary to add new enum values to these tables until they're needed for something.)
1. **Manually update the "Map from enum string back to enum number" tables.**
    - Inspect the `webgpu.h` diff for changes to these enums. (These tables need to be complete so that we can handle any enum string the browser gives us.)
1. Update Emscripten's auto-generated files:

    ```
    emcc --clear-cache
    ./tools/maint/gen_struct_info.py
    ./tools/maint/gen_struct_info.py --wasm64
    ./tools/maint/gen_sig_info.py
    ```

## Testing

There is a `browser.test_webgpu_basic_rendering` with minimal WebGPU API testing that can be handy to test manually before making a contribution. Use `browser64.test_webgpu_basic_rendering` to test the MEMORY64 build.

```
test/runner browser.test_webgpu_basic_rendering
test/runner browser64.test_webgpu_basic_rendering
```

You may need to specify extra browser cmd args to assign the WebGPU supported browser, which is needed if you work on linux where WebGPU is not enabled by default in chrome at present.

```
test/runner browser.test_webgpu_basic_rendering --browser="google-chrome-unstable --enable-unsafe-webgpu --enable-features=Vulkan,UseSkiaRenderer"
```

Alternatively you can test your emscripten updates by building the source file, and then serve (e.g. use node http-server) and view in browser to make sure things work fine.

```
emcc --clear-cache
emcc test/webgpu_basic_rendering.cpp -sUSE_WEBGPU -o path/to/index.html
```
