@plasius/gpu-worker 0.1.0 → 0.1.2
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/CHANGELOG.md +47 -1
- package/README.md +86 -9
- package/dist/index.cjs +493 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +481 -9
- package/dist/index.js.map +1 -1
- package/dist/worker.wgsl +23 -120
- package/package.json +3 -2
- package/src/index.js +533 -8
- package/src/worker.wgsl +23 -120
package/CHANGELOG.md
CHANGED
|
@@ -20,6 +20,51 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
20
20
|
- **Security**
|
|
21
21
|
- (placeholder)
|
|
22
22
|
|
|
23
|
+
## [0.1.2] - 2026-01-24
|
|
24
|
+
|
|
25
|
+
- **Added**
|
|
26
|
+
- `loadJobWgsl` to register multiple job WGSL modules and receive `job_type` ids.
|
|
27
|
+
- Job-aware `assembleWorkerWgsl` that appends registered jobs and generates a dispatch wrapper.
|
|
28
|
+
- Optional debug mode for WGSL identifier clash detection during assembly.
|
|
29
|
+
- `loadQueueWgsl` helper that can apply queue compatibility renames during load.
|
|
30
|
+
- `createWorkerLoop` helper to drive worker/job compute dispatch at max or throttled rates.
|
|
31
|
+
- Demo denoise job WGSL (`demo/jobs/denoise.wgsl`) with a compute pass + present shader.
|
|
32
|
+
- Temporal denoise history buffer in the demo to stabilize jittered lighting.
|
|
33
|
+
|
|
34
|
+
- **Changed**
|
|
35
|
+
- Demo visuals now render a campfire scene with deferred lighting (G-buffer + fullscreen lighting pass).
|
|
36
|
+
- Demo now builds per-type worklists from queue jobs and uses indirect draws for render jobs alongside physics jobs.
|
|
37
|
+
- `src/worker.wgsl` is now a minimal worker template; demo kernels live in `demo/jobs/*.wgsl`.
|
|
38
|
+
- Demo job shaders are split into `demo/jobs/common.wgsl`, `demo/jobs/physics.job.wgsl`, and `demo/jobs/render.job.wgsl`.
|
|
39
|
+
- Demo lighting sampling now uses screen-space jitter to avoid world-space banding artifacts.
|
|
40
|
+
- `assembleWorkerWgsl` can now consume a registry or explicit job list and emit a dispatching `process_job`.
|
|
41
|
+
- `assembleWorkerWgsl` now applies queue compatibility renames (e.g., `JobMeta` -> `JobDesc`) by default.
|
|
42
|
+
|
|
43
|
+
- **Fixed**
|
|
44
|
+
- Reduced diagonal banding artifacts in the demo lighting pass.
|
|
45
|
+
|
|
46
|
+
- **Security**
|
|
47
|
+
- (placeholder)
|
|
48
|
+
|
|
49
|
+
## [0.1.1] - 2026-01-23
|
|
50
|
+
|
|
51
|
+
- **Added**
|
|
52
|
+
- `assembleWorkerWgsl` now accepts optional queue WGSL overrides for local demos.
|
|
53
|
+
|
|
54
|
+
- **Changed**
|
|
55
|
+
- Demo now simulates millions of instanced objects with range checks, bounding spheres/AABBs, and face contact stats.
|
|
56
|
+
- **Breaking:** Queue bindings updated to remove the payload arena and use payload offsets into caller-managed buffers.
|
|
57
|
+
- Demo updated to match the new payload-handle layout.
|
|
58
|
+
- **Breaking:** Queue bindings now use job metadata and a variable-size payload arena.
|
|
59
|
+
- Worker job payloads are read from the output payload buffer using `output_stride`.
|
|
60
|
+
- Demo updated to emit job metadata and payload buffers.
|
|
61
|
+
|
|
62
|
+
- **Fixed**
|
|
63
|
+
- Demo can load a local queue WGSL to avoid mismatched dependency versions.
|
|
64
|
+
|
|
65
|
+
- **Security**
|
|
66
|
+
- (placeholder)
|
|
67
|
+
|
|
23
68
|
## [0.1.0] - 2026-01-22
|
|
24
69
|
|
|
25
70
|
- **Added**
|
|
@@ -69,6 +114,7 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
69
114
|
|
|
70
115
|
---
|
|
71
116
|
|
|
72
|
-
[Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.
|
|
117
|
+
[Unreleased]: https://github.com/Plasius-LTD/gpu-worker/compare/v0.1.2...HEAD
|
|
73
118
|
[0.1.0-beta.1]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0-beta.1
|
|
74
119
|
[0.1.0]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.0
|
|
120
|
+
[0.1.2]: https://github.com/Plasius-LTD/gpu-worker/releases/tag/v0.1.2
|
package/README.md
CHANGED
|
@@ -15,38 +15,115 @@ npm install @plasius/gpu-worker
|
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
```js
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
assembleWorkerWgsl,
|
|
20
|
+
createWorkerLoop,
|
|
21
|
+
loadJobWgsl,
|
|
22
|
+
loadWorkerWgsl,
|
|
23
|
+
} from "@plasius/gpu-worker";
|
|
19
24
|
|
|
20
25
|
const workerWgsl = await loadWorkerWgsl();
|
|
21
|
-
const
|
|
26
|
+
const jobType = await loadJobWgsl({
|
|
27
|
+
wgsl: `
|
|
28
|
+
fn process_job(job_index: u32, job_type: u32, payload_words: u32) {
|
|
29
|
+
// job logic here
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
label: "physics",
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const shaderCode = await assembleWorkerWgsl(workerWgsl, { debug: true });
|
|
22
36
|
// Pass shaderCode to device.createShaderModule({ code: shaderCode })
|
|
23
37
|
```
|
|
24
38
|
|
|
39
|
+
`loadJobWgsl` registers job WGSL and returns the assigned `job_type` index.
|
|
40
|
+
Call `assembleWorkerWgsl` again after registering new jobs to rebuild the
|
|
41
|
+
combined WGSL. Job types are assigned in registration order, so keep the
|
|
42
|
+
registration order stable across rebuilds if you need deterministic ids.
|
|
43
|
+
|
|
44
|
+
`assembleWorkerWgsl` also accepts an optional second argument to override the
|
|
45
|
+
queue WGSL source: `assembleWorkerWgsl(workerWgsl, { queueWgsl, queueUrl, fetcher })`.
|
|
46
|
+
By default it applies queue compatibility renames (for example `JobMeta` -> `JobDesc`);
|
|
47
|
+
set `queueCompat: false` to disable that behavior.
|
|
48
|
+
If you are concatenating WGSL manually, `loadQueueWgsl` provides the same
|
|
49
|
+
compatibility renames by default: `loadQueueWgsl({ url, fetcher, queueCompat: false })`.
|
|
50
|
+
|
|
51
|
+
To bypass the registry, pass jobs directly:
|
|
52
|
+
```js
|
|
53
|
+
const shaderCode = await assembleWorkerWgsl(workerWgsl, {
|
|
54
|
+
jobs: [{ wgsl: jobA }, { wgsl: jobB, label: "lighting" }],
|
|
55
|
+
debug: true,
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When assembling jobs, each job WGSL must define
|
|
60
|
+
`process_job(job_index, job_type, payload_words)`. The assembler rewrites each
|
|
61
|
+
job's `process_job` to a unique name and generates a dispatcher based on
|
|
62
|
+
`job_type`. Set `debug: true` to detect identifier clashes across appended WGSL.
|
|
63
|
+
|
|
64
|
+
To run the worker loop at the highest practical rate (or a target rate), use the
|
|
65
|
+
helper:
|
|
66
|
+
```js
|
|
67
|
+
const loop = createWorkerLoop({
|
|
68
|
+
device,
|
|
69
|
+
worker: { pipeline: workerPipeline, bindGroups: [queueBindGroup, simBindGroup] },
|
|
70
|
+
jobs: [
|
|
71
|
+
{ pipeline: physicsPipeline, bindGroups: [queueBindGroup, simBindGroup], workgroups: physicsWorkgroups },
|
|
72
|
+
{ pipeline: renderIndirectPipeline, bindGroups: [queueBindGroup, simBindGroup], workgroups: 1 },
|
|
73
|
+
],
|
|
74
|
+
workgroupSize: 64,
|
|
75
|
+
maxJobsPerDispatch: queueCapacity,
|
|
76
|
+
// rateHz: 120, // optional throttle; omit for animation-frame cadence
|
|
77
|
+
});
|
|
78
|
+
loop.start();
|
|
79
|
+
```
|
|
80
|
+
|
|
25
81
|
## What this is
|
|
26
82
|
- A minimal GPU worker layer that combines a lock-free queue with user WGSL jobs.
|
|
27
83
|
- A helper to assemble WGSL modules with queue helpers included.
|
|
28
84
|
- A reference job format for fixed-size job dispatch (u32 indices).
|
|
29
85
|
|
|
30
86
|
## Demo
|
|
31
|
-
The demo enqueues
|
|
32
|
-
|
|
87
|
+
The demo enqueues physics and render jobs on the GPU, builds per-type worklists, runs the
|
|
88
|
+
physics kernel, and uses an indirect draw for the particle pass. Install dependencies first
|
|
89
|
+
so the lock-free queue package is available for the browser import map.
|
|
33
90
|
|
|
34
91
|
```
|
|
35
92
|
npm install
|
|
36
|
-
|
|
93
|
+
npm run demo
|
|
37
94
|
```
|
|
38
95
|
|
|
39
96
|
Then open `http://localhost:8000/demo/`.
|
|
40
97
|
|
|
98
|
+
### HTTPS demo
|
|
99
|
+
WebGPU requires a secure context. For non-localhost access, run the HTTPS demo server.
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
mkdir -p demo/certs
|
|
103
|
+
mkcert -key-file demo/certs/localhost-key.pem -cert-file demo/certs/localhost.pem localhost 127.0.0.1 ::1
|
|
104
|
+
# or
|
|
105
|
+
openssl req -x509 -newkey rsa:2048 -nodes -keyout demo/certs/localhost-key.pem -out demo/certs/localhost.pem -days 365 -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
|
|
106
|
+
npm run demo:https
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then open `https://localhost:8443/demo/`. If you use a different hostname/IP, generate a
|
|
110
|
+
certificate for that name and set `DEMO_HOST`, `DEMO_PORT`, `DEMO_TLS_CERT`, and
|
|
111
|
+
`DEMO_TLS_KEY` as needed.
|
|
112
|
+
|
|
41
113
|
## Build Outputs
|
|
42
114
|
|
|
43
115
|
`npm run build` emits `dist/index.js`, `dist/index.cjs`, and `dist/worker.wgsl`.
|
|
44
116
|
|
|
45
117
|
## Files
|
|
46
|
-
- `demo/index.html`: Loads the
|
|
47
|
-
- `demo/main.js`: WebGPU setup,
|
|
48
|
-
- `
|
|
118
|
+
- `demo/index.html`: Loads the WebGPU demo.
|
|
119
|
+
- `demo/main.js`: WebGPU setup, queue jobs, physics worklists, and indirect draw.
|
|
120
|
+
- `demo/jobs/common.wgsl`: Shared WGSL definitions for demo jobs.
|
|
121
|
+
- `demo/jobs/physics.job.wgsl`: Physics job kernel (worklist + integration).
|
|
122
|
+
- `demo/jobs/render.job.wgsl`: Render job kernel (worklist + indirect args).
|
|
123
|
+
- `src/worker.wgsl`: Minimal worker entry point template (dequeue + `process_job` hook).
|
|
49
124
|
- `src/index.js`: Helper functions to load/assemble WGSL.
|
|
50
125
|
|
|
51
126
|
## Job shape
|
|
52
|
-
Jobs are `
|
|
127
|
+
Jobs are variable-length payloads stored in a caller-managed buffer. Each job supplies `job_type`, `payload_offset`, and `payload_words` metadata plus a payload stored in the input payload buffer. For simple cases, use a single-word payload containing an index into your workload array.
|
|
128
|
+
|
|
129
|
+
Set `output_stride` in queue params to the maximum payload size you want copied out for a job; `job_type` can be used by schedulers to route work to different kernels. The queue mirrors input metadata into `output_jobs` and optionally copies payloads into `output_payloads`.
|