@simulatte/webgpu 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API_CONTRACT.md +11 -1
- package/CHANGELOG.md +82 -0
- package/COMPAT_SCOPE.md +20 -6
- package/LAYERING_PLAN.md +257 -0
- package/README.md +242 -61
- package/SUPPORT_CONTRACTS.md +353 -0
- package/ZIG_SOURCE_INVENTORY.md +468 -0
- package/assets/package-surface-cube-snapshot.svg +7 -7
- package/headless-webgpu-comparison.md +3 -3
- package/native/doe_napi.c +110 -17
- package/package.json +7 -3
- package/prebuilds/darwin-arm64/doe_napi.node +0 -0
- package/prebuilds/darwin-arm64/libwebgpu_doe.dylib +0 -0
- package/prebuilds/darwin-arm64/metadata.json +5 -5
- package/prebuilds/linux-x64/doe_napi.node +0 -0
- package/prebuilds/linux-x64/libwebgpu_dawn.so +0 -0
- package/prebuilds/linux-x64/libwebgpu_doe.so +0 -0
- package/prebuilds/linux-x64/metadata.json +26 -0
- package/src/bun-ffi.js +3 -2
- package/src/bun.js +2 -2
- package/src/index.js +114 -15
- package/src/runtime_cli.js +3 -1
package/API_CONTRACT.md
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Contract version: `v1`
|
|
4
4
|
|
|
5
|
-
Scope:
|
|
5
|
+
Scope: current single-surface headless WebGPU package contract for Node.js and
|
|
6
|
+
Bun, plus Doe runtime helpers used by benchmarking, CI, and artifact-backed
|
|
7
|
+
comparison workflows.
|
|
8
|
+
|
|
9
|
+
This is the current single-surface package contract.
|
|
10
|
+
For the proposed future layered `core` vs `full` support split, see
|
|
11
|
+
`SUPPORT_CONTRACTS.md`.
|
|
12
|
+
|
|
13
|
+
This contract covers package-surface GPU access, provider metadata, and helper
|
|
14
|
+
entrypoints. It does not promise DOM/canvas ownership or browser-process
|
|
15
|
+
parity.
|
|
6
16
|
|
|
7
17
|
## Node runtime API
|
|
8
18
|
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@simulatte/webgpu` are documented in this file.
|
|
4
|
+
|
|
5
|
+
This changelog is package-facing and release-oriented. Early entries were
|
|
6
|
+
retrofitted from package version history and package-surface commits so the npm
|
|
7
|
+
package has a conventional release history alongside the broader Fawn status
|
|
8
|
+
and process documents.
|
|
9
|
+
|
|
10
|
+
## [0.2.3] - 2026-03-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- macOS arm64 (Metal) prebuilds shipped alongside existing Linux x64 (Vulkan).
|
|
15
|
+
- Monte Carlo pi estimation example in the README, replacing the trivial
|
|
16
|
+
buffer-readback snippet with a real GPU compute demonstration.
|
|
17
|
+
- "Verify your install" section with `npm run smoke` and `npm test` guidance.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Restructured package README for consumers: examples, quickstart, and
|
|
22
|
+
verification first; building from source and Fawn developer context at the end.
|
|
23
|
+
- Fixed broken README image links to use bundled asset paths instead of dead
|
|
24
|
+
raw GitHub URLs.
|
|
25
|
+
- Root Fawn README now directs package users to the package README.
|
|
26
|
+
- Fixed 4 Metal benchmark workload contracts with asymmetric repeat accounting;
|
|
27
|
+
all 31 comparable workloads now have symmetric `leftCommandRepeat` /
|
|
28
|
+
`rightCommandRepeat`.
|
|
29
|
+
|
|
30
|
+
## [0.2.2] - 2026-03-10
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- Added a Linux regression test guarding the drop-in loader against reopening
|
|
35
|
+
`libwebgpu_doe` as its own target WebGPU provider.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Fixed Linux drop-in proc resolution so workspace-local Node and Bun package
|
|
40
|
+
loads resolve Dawn/WebGPU target symbols instead of recursing through the Doe
|
|
41
|
+
drop-in library.
|
|
42
|
+
- Validated the package release surface on Linux Vulkan with addon build, smoke,
|
|
43
|
+
Node tests, prebuild assembly, and Bun contract tests.
|
|
44
|
+
|
|
45
|
+
## [0.2.1] - 2026-03-07
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
- Added package repository, homepage, and issue metadata.
|
|
50
|
+
- Added packaged README asset generation support and shipped package assets.
|
|
51
|
+
- Added additional package-surface contract documents and metadata schemas to
|
|
52
|
+
the published file set.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Refined the package surface around the canonical Doe-backed Node and Bun
|
|
57
|
+
entrypoints.
|
|
58
|
+
- Expanded package publishing inputs to include scripts, prebuilds, and package
|
|
59
|
+
documentation needed for reproducible installs.
|
|
60
|
+
|
|
61
|
+
## [0.2.0] - 2026-03-06
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- Promoted the package to the public `@simulatte/webgpu` name.
|
|
66
|
+
- Added Node and Bun entrypoints, benchmark CLI wrappers, and a native addon
|
|
67
|
+
bridge for headless WebGPU execution.
|
|
68
|
+
- Added package install, build, test, smoke, and prebuild workflows.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- Replaced the earlier placeholder package metadata with a real publishable
|
|
73
|
+
package surface for Doe-backed headless compute and benchmarking.
|
|
74
|
+
- Shifted the package from scaffold-only metadata to a documented package with
|
|
75
|
+
explicit published files and package-surface contracts.
|
|
76
|
+
|
|
77
|
+
## [0.0.1] - 2026-03-01
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- Initial package scaffold for the Doe WebGPU package surface under
|
|
82
|
+
`nursery/webgpu`.
|
package/COMPAT_SCOPE.md
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
# Compatibility Scope: what we actually need
|
|
2
2
|
|
|
3
|
-
This note narrows
|
|
3
|
+
This note narrows compatibility work to concrete headless integration value for
|
|
4
|
+
the current package surface.
|
|
4
5
|
|
|
5
6
|
## Required now
|
|
6
7
|
|
|
7
|
-
1. Stable
|
|
8
|
-
2.
|
|
8
|
+
1. Stable headless Node/Bun provider behavior for real Doe-native execution.
|
|
9
|
+
2. Stable command/trace orchestration for benchmark and CI pipelines.
|
|
10
|
+
3. Reliable wrappers for:
|
|
9
11
|
- Doe native bench runs
|
|
10
12
|
- Dawn-vs-Doe compare runs
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
4. Deterministic artifact paths and non-zero exit-code propagation.
|
|
14
|
+
5. Minimal convenience entrypoints for Node consumers:
|
|
13
15
|
- `create(args?)`
|
|
14
16
|
- `globals`
|
|
15
17
|
- `requestAdapter`/`requestDevice` convenience helpers
|
|
16
18
|
- `setupGlobals` for `navigator.gpu` + enum bootstrap
|
|
17
19
|
|
|
20
|
+
The point of this package is headless GPU work in Node/Bun: compute, offscreen
|
|
21
|
+
execution, benchmarking, and CI. Compatibility work should serve those
|
|
22
|
+
surfaces first.
|
|
23
|
+
|
|
18
24
|
## Optional later (only when demanded by integrations)
|
|
19
25
|
|
|
20
26
|
1. Minimal constants compatibility:
|
|
@@ -29,4 +35,12 @@ This note narrows optional parity work to concrete integration value.
|
|
|
29
35
|
|
|
30
36
|
Decision rule:
|
|
31
37
|
|
|
32
|
-
- Add parity features only after a concrete integration
|
|
38
|
+
- Add parity features only after a concrete headless integration is blocked by
|
|
39
|
+
a missing capability and cannot be addressed by the existing package,
|
|
40
|
+
bridge, or CLI contract.
|
|
41
|
+
|
|
42
|
+
Layering note:
|
|
43
|
+
|
|
44
|
+
- this file describes the current package surface and its present non-goals
|
|
45
|
+
- proposed future `core` vs `full` support contracts are defined separately in
|
|
46
|
+
`SUPPORT_CONTRACTS.md`
|
package/LAYERING_PLAN.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Proposed layering plan for core and full
|
|
2
|
+
|
|
3
|
+
Plan status: `draft`
|
|
4
|
+
|
|
5
|
+
Scope:
|
|
6
|
+
|
|
7
|
+
- future Doe runtime/package sharding for headless WebGPU
|
|
8
|
+
- architecture and refactor sequencing only
|
|
9
|
+
- no current runtime behavior changes
|
|
10
|
+
|
|
11
|
+
This plan exists to keep the future `core` and `full` split honest before any
|
|
12
|
+
Zig source moves begin.
|
|
13
|
+
|
|
14
|
+
It answers four questions:
|
|
15
|
+
|
|
16
|
+
1. what boundary is being enforced
|
|
17
|
+
2. how that boundary is enforced in code review and CI
|
|
18
|
+
3. how capability coverage and gates split once the boundary exists
|
|
19
|
+
4. what order the refactor should happen in
|
|
20
|
+
|
|
21
|
+
Use this together with:
|
|
22
|
+
|
|
23
|
+
- `SUPPORT_CONTRACTS.md` for product/support scope
|
|
24
|
+
- `API_CONTRACT.md` for the current single-surface package contract
|
|
25
|
+
- `COMPAT_SCOPE.md` for current package non-goals
|
|
26
|
+
- `ZIG_SOURCE_INVENTORY.md` for the current `zig/src` file map
|
|
27
|
+
|
|
28
|
+
## Current state
|
|
29
|
+
|
|
30
|
+
The repo is now partially physically split into `core` and `full`, but the public façade boundary is still being reduced.
|
|
31
|
+
|
|
32
|
+
Current reality:
|
|
33
|
+
|
|
34
|
+
1. `zig/src/core/` and `zig/src/full/` are now real source subtrees with canonical implementations for the first runtime split slices.
|
|
35
|
+
2. The old root ABI shims (`zig/src/wgpu_types.zig`, `zig/src/wgpu_loader.zig`) have now been retired; the remaining root compatibility façades are narrower command/resource surfaces kept only while callers finish retargeting.
|
|
36
|
+
3. Canonical command partition and command dispatch now live in `zig/src/core/{command_partition.zig,command_dispatch.zig}` and `zig/src/full/{command_partition.zig,command_dispatch.zig}`.
|
|
37
|
+
4. Canonical texture command handling now lives in `zig/src/core/resource/wgpu_texture_commands.zig`; canonical sampler and surface command handling now lives in `zig/src/full/render/wgpu_sampler_commands.zig` and `zig/src/full/surface/wgpu_surface_commands.zig`.
|
|
38
|
+
5. `zig/src/wgpu_commands.zig`, `zig/src/wgpu_resources.zig`, and `zig/src/wgpu_extended_commands.zig` are now compatibility façades over the canonical subtrees, while `zig/src/webgpu_ffi.zig` remains the public façade and owner of `WebGPUBackend`.
|
|
39
|
+
6. Dedicated Zig test lanes now exist as `zig build test-core` and `zig build test-full`, but split coverage remains thin and capability tracking is still represented by one shared coverage ledger.
|
|
40
|
+
7. The JS package still exposes a single surface today.
|
|
41
|
+
|
|
42
|
+
That means this plan is now materially physicalized in the tree, and the remaining semantic split is concentrated in the public façade files and backend roots.
|
|
43
|
+
|
|
44
|
+
## Boundary definition
|
|
45
|
+
|
|
46
|
+
The target architecture is:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
Doe core
|
|
50
|
+
^
|
|
51
|
+
|
|
|
52
|
+
Doe full
|
|
53
|
+
^
|
|
54
|
+
|
|
|
55
|
+
Chromium Track A runtime artifact lane
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Rules:
|
|
59
|
+
|
|
60
|
+
1. `full` composes `core`; it does not toggle `core`.
|
|
61
|
+
2. `core` must never import `full`.
|
|
62
|
+
3. `full` may depend on `core` Zig modules, Lean modules, build outputs, and JS
|
|
63
|
+
helpers.
|
|
64
|
+
4. Chromium Track A depends on the full runtime artifact and browser-specific
|
|
65
|
+
gates, not on npm package layout.
|
|
66
|
+
|
|
67
|
+
The anti-bleed rule is the core of the design:
|
|
68
|
+
|
|
69
|
+
- no `if full_enabled` branches inside `core`
|
|
70
|
+
- no `full` fields added to `core` structs
|
|
71
|
+
- no browser-policy logic added to `full`
|
|
72
|
+
|
|
73
|
+
## Import fence rule
|
|
74
|
+
|
|
75
|
+
This is the primary long-term enforcement rule.
|
|
76
|
+
|
|
77
|
+
### Contract
|
|
78
|
+
|
|
79
|
+
1. `zig/src/core/**` may not import any file under `zig/src/full/**`
|
|
80
|
+
2. `lean/Fawn/Core/**` may not import any file under `lean/Fawn/Full/**`
|
|
81
|
+
3. package-level `core` entrypoints may not import `full` entrypoints
|
|
82
|
+
4. any exception requires redesign, not a one-off waiver
|
|
83
|
+
|
|
84
|
+
### CI enforcement
|
|
85
|
+
|
|
86
|
+
The dedicated import-fence check should fail if:
|
|
87
|
+
|
|
88
|
+
1. a Zig file under `core` references `full/`
|
|
89
|
+
2. a Lean file under `Core` references `Full`
|
|
90
|
+
3. a package `core` entrypoint reaches into a `full`-only module
|
|
91
|
+
|
|
92
|
+
The check should be a simple, explicit path-dependency audit. This is not a
|
|
93
|
+
lint preference; it is a release-blocking architectural boundary.
|
|
94
|
+
|
|
95
|
+
## Struct wrapping rule
|
|
96
|
+
|
|
97
|
+
`full` must extend `core` by composition, never by mutating `core` types in
|
|
98
|
+
place.
|
|
99
|
+
|
|
100
|
+
### Contract
|
|
101
|
+
|
|
102
|
+
1. if `full` needs shared state, it holds a `core` value or handle
|
|
103
|
+
2. if `full` needs extra state, that state lives in a `full` wrapper type
|
|
104
|
+
3. `core` structs may not gain render/surface/full-only fields just because
|
|
105
|
+
`full` needs them
|
|
106
|
+
4. `core` APIs may expose stable extension points, but not latent `full`
|
|
107
|
+
payload slots
|
|
108
|
+
|
|
109
|
+
### Example direction
|
|
110
|
+
|
|
111
|
+
Good shape:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
full.RenderPipeline
|
|
115
|
+
- core_pipeline_layout: core.PipelineLayout
|
|
116
|
+
- full_render_state: ...
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Bad shape:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
core.PipelineLayout
|
|
123
|
+
- maybe_render_state_if_full_enabled: ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The intent is to keep `core` independently understandable, buildable, and
|
|
127
|
+
benchmarked.
|
|
128
|
+
|
|
129
|
+
## Coverage split rule
|
|
130
|
+
|
|
131
|
+
The current shared capability ledger is not enough once `core` and `full`
|
|
132
|
+
become separate release surfaces.
|
|
133
|
+
|
|
134
|
+
### Target split
|
|
135
|
+
|
|
136
|
+
1. `config/webgpu-core-coverage.json`
|
|
137
|
+
- only `core` contractual capabilities
|
|
138
|
+
2. `config/webgpu-full-coverage.json`
|
|
139
|
+
- `core` plus `full` contractual capabilities
|
|
140
|
+
3. Chromium Track A keeps its own browser/drop-in evidence and must not be
|
|
141
|
+
represented as mere package coverage
|
|
142
|
+
|
|
143
|
+
### Gate split
|
|
144
|
+
|
|
145
|
+
`core` gates should validate:
|
|
146
|
+
|
|
147
|
+
1. core package contract
|
|
148
|
+
2. core CTS subset
|
|
149
|
+
3. core package-surface benchmark cells
|
|
150
|
+
4. explicit unsupported taxonomy outside core scope
|
|
151
|
+
|
|
152
|
+
`full` gates should validate:
|
|
153
|
+
|
|
154
|
+
1. all core gates
|
|
155
|
+
2. full package contract
|
|
156
|
+
3. expanded CTS subset for render/lifecycle/query coverage
|
|
157
|
+
4. full package-surface benchmark cells
|
|
158
|
+
5. explicit unsupported taxonomy outside full scope
|
|
159
|
+
|
|
160
|
+
Track A gates remain separate:
|
|
161
|
+
|
|
162
|
+
1. drop-in symbol completeness
|
|
163
|
+
2. drop-in behavior suite
|
|
164
|
+
3. browser replay and trace parity
|
|
165
|
+
4. browser performance claimability
|
|
166
|
+
|
|
167
|
+
## Proposed source layout
|
|
168
|
+
|
|
169
|
+
Target layout:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
zig/src/core/
|
|
173
|
+
mod.zig
|
|
174
|
+
trace/
|
|
175
|
+
replay/
|
|
176
|
+
abi/
|
|
177
|
+
resource/
|
|
178
|
+
queue/
|
|
179
|
+
compute/
|
|
180
|
+
backend/common/
|
|
181
|
+
backend/{metal,vulkan,d3d12}/core/
|
|
182
|
+
|
|
183
|
+
zig/src/full/
|
|
184
|
+
mod.zig
|
|
185
|
+
render/
|
|
186
|
+
surface/
|
|
187
|
+
lifecycle/
|
|
188
|
+
backend/{metal,vulkan,d3d12}/full/
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Matching Lean layout:
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
lean/Fawn/Core/
|
|
195
|
+
lean/Fawn/Full/
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Matching package layout can be one of:
|
|
199
|
+
|
|
200
|
+
1. one package with scoped exports
|
|
201
|
+
2. separate packages with separate contracts
|
|
202
|
+
|
|
203
|
+
Packaging choice is secondary. The source boundary must come first.
|
|
204
|
+
|
|
205
|
+
## Refactor order
|
|
206
|
+
|
|
207
|
+
Do not start by renaming packages.
|
|
208
|
+
|
|
209
|
+
Recommended order:
|
|
210
|
+
|
|
211
|
+
1. freeze support contracts
|
|
212
|
+
- define what `core` and `full` promise
|
|
213
|
+
2. add import-fence CI checks
|
|
214
|
+
- enforce the one-way dependency before extraction starts
|
|
215
|
+
3. add split coverage ledgers and split gate entrypoints
|
|
216
|
+
- even if both initially point at the current shared runtime
|
|
217
|
+
4. identify shared runtime modules that are genuinely `core`
|
|
218
|
+
- trace, replay, buffers, queue, compute, shared resource model
|
|
219
|
+
5. identify `full`-only modules
|
|
220
|
+
- render, surface, broader lifecycle/parity layers
|
|
221
|
+
6. extract `full` wrappers around `core` types
|
|
222
|
+
- composition only
|
|
223
|
+
7. move render/surface code out of the shared tree
|
|
224
|
+
- no behavior change intended during extraction
|
|
225
|
+
8. split package/API contracts
|
|
226
|
+
- only after the runtime boundary is real
|
|
227
|
+
9. retarget Chromium Track A to the full runtime artifact contract
|
|
228
|
+
- no npm package dependency in architecture docs
|
|
229
|
+
|
|
230
|
+
## Review checklist for future changes
|
|
231
|
+
|
|
232
|
+
Any future patch touching this split should answer:
|
|
233
|
+
|
|
234
|
+
1. does `core` now depend on `full` anywhere
|
|
235
|
+
2. did a `core` struct gain a `full`-only field
|
|
236
|
+
3. did a coverage or gate responsibility move without contract updates
|
|
237
|
+
4. did a browser-owned behavior get assigned to `core` or `full`
|
|
238
|
+
5. did packaging get ahead of the runtime boundary
|
|
239
|
+
|
|
240
|
+
If any answer is yes, the patch should be treated as architecture drift until
|
|
241
|
+
the contract is updated or the design is corrected.
|
|
242
|
+
|
|
243
|
+
## Immediate next artifacts
|
|
244
|
+
|
|
245
|
+
The earliest structural groundwork now exists: the inventory and import-fence check are in place, the first canonical `core/` and `full/` subtrees exist, and the legacy root command/resource files are compatibility façades.
|
|
246
|
+
|
|
247
|
+
The next technical artifacts should focus on the remaining semantic boundary:
|
|
248
|
+
|
|
249
|
+
1. split coverage contracts for `core` and `full`
|
|
250
|
+
2. classify tests and Lean proofs against the new `core`/`full` boundary
|
|
251
|
+
3. shrink the remaining public façade files:
|
|
252
|
+
- `model.zig`
|
|
253
|
+
- `webgpu_ffi.zig`
|
|
254
|
+
- backend root modules
|
|
255
|
+
4. retire root compatibility façades once callers stop importing them
|
|
256
|
+
|
|
257
|
+
The extraction work should now spend its effort on the remaining public boundary, not on re-moving files that already have canonical homes.
|