@motion-core/motion-gpu 0.4.1 → 0.5.0
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/README.md +99 -0
- package/dist/advanced.d.ts +1 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +14 -6
- package/dist/core/advanced.d.ts +1 -0
- package/dist/core/advanced.d.ts.map +1 -0
- package/dist/core/advanced.js +14 -5
- package/dist/core/compute-shader.d.ts +87 -0
- package/dist/core/compute-shader.d.ts.map +1 -0
- package/dist/core/compute-shader.js +205 -0
- package/dist/core/compute-shader.js.map +1 -0
- package/dist/core/current-value.d.ts +1 -0
- package/dist/core/current-value.d.ts.map +1 -0
- package/dist/core/current-value.js +35 -34
- package/dist/core/current-value.js.map +1 -0
- package/dist/core/error-diagnostics.d.ts +1 -0
- package/dist/core/error-diagnostics.d.ts.map +1 -0
- package/dist/core/error-diagnostics.js +70 -137
- package/dist/core/error-diagnostics.js.map +1 -0
- package/dist/core/error-report.d.ts +2 -1
- package/dist/core/error-report.d.ts.map +1 -0
- package/dist/core/error-report.js +247 -233
- package/dist/core/error-report.js.map +1 -0
- package/dist/core/frame-registry.d.ts +1 -0
- package/dist/core/frame-registry.d.ts.map +1 -0
- package/dist/core/frame-registry.js +546 -662
- package/dist/core/frame-registry.js.map +1 -0
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -12
- package/dist/core/material-preprocess.d.ts +1 -0
- package/dist/core/material-preprocess.d.ts.map +1 -0
- package/dist/core/material-preprocess.js +131 -152
- package/dist/core/material-preprocess.js.map +1 -0
- package/dist/core/material.d.ts +23 -6
- package/dist/core/material.d.ts.map +1 -0
- package/dist/core/material.js +290 -317
- package/dist/core/material.js.map +1 -0
- package/dist/core/recompile-policy.d.ts +1 -0
- package/dist/core/recompile-policy.d.ts.map +1 -0
- package/dist/core/recompile-policy.js +18 -13
- package/dist/core/recompile-policy.js.map +1 -0
- package/dist/core/render-graph.d.ts +8 -3
- package/dist/core/render-graph.d.ts.map +1 -0
- package/dist/core/render-graph.js +77 -68
- package/dist/core/render-graph.js.map +1 -0
- package/dist/core/render-targets.d.ts +1 -0
- package/dist/core/render-targets.d.ts.map +1 -0
- package/dist/core/render-targets.js +52 -53
- package/dist/core/render-targets.js.map +1 -0
- package/dist/core/renderer.d.ts +1 -0
- package/dist/core/renderer.d.ts.map +1 -0
- package/dist/core/renderer.js +1337 -1081
- package/dist/core/renderer.js.map +1 -0
- package/dist/core/runtime-loop.d.ts +3 -2
- package/dist/core/runtime-loop.d.ts.map +1 -0
- package/dist/core/runtime-loop.js +353 -362
- package/dist/core/runtime-loop.js.map +1 -0
- package/dist/core/scheduler-helpers.d.ts +1 -0
- package/dist/core/scheduler-helpers.d.ts.map +1 -0
- package/dist/core/scheduler-helpers.js +52 -51
- package/dist/core/scheduler-helpers.js.map +1 -0
- package/dist/core/shader.d.ts +10 -1
- package/dist/core/shader.d.ts.map +1 -0
- package/dist/core/shader.js +109 -115
- package/dist/core/shader.js.map +1 -0
- package/dist/core/storage-buffers.d.ts +37 -0
- package/dist/core/storage-buffers.d.ts.map +1 -0
- package/dist/core/storage-buffers.js +95 -0
- package/dist/core/storage-buffers.js.map +1 -0
- package/dist/core/texture-loader.d.ts +1 -0
- package/dist/core/texture-loader.d.ts.map +1 -0
- package/dist/core/texture-loader.js +209 -273
- package/dist/core/texture-loader.js.map +1 -0
- package/dist/core/textures.d.ts +13 -0
- package/dist/core/textures.d.ts.map +1 -0
- package/dist/core/textures.js +111 -116
- package/dist/core/textures.js.map +1 -0
- package/dist/core/types.d.ts +147 -4
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +0 -4
- package/dist/core/uniforms.d.ts +1 -0
- package/dist/core/uniforms.d.ts.map +1 -0
- package/dist/core/uniforms.js +170 -191
- package/dist/core/uniforms.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -6
- package/dist/passes/BlitPass.d.ts +1 -0
- package/dist/passes/BlitPass.d.ts.map +1 -0
- package/dist/passes/BlitPass.js +23 -18
- package/dist/passes/BlitPass.js.map +1 -0
- package/dist/passes/ComputePass.d.ts +83 -0
- package/dist/passes/ComputePass.d.ts.map +1 -0
- package/dist/passes/ComputePass.js +92 -0
- package/dist/passes/ComputePass.js.map +1 -0
- package/dist/passes/CopyPass.d.ts +1 -0
- package/dist/passes/CopyPass.d.ts.map +1 -0
- package/dist/passes/CopyPass.js +58 -52
- package/dist/passes/CopyPass.js.map +1 -0
- package/dist/passes/FullscreenPass.d.ts +1 -0
- package/dist/passes/FullscreenPass.d.ts.map +1 -0
- package/dist/passes/FullscreenPass.js +127 -130
- package/dist/passes/FullscreenPass.js.map +1 -0
- package/dist/passes/PingPongComputePass.d.ts +104 -0
- package/dist/passes/PingPongComputePass.d.ts.map +1 -0
- package/dist/passes/PingPongComputePass.js +132 -0
- package/dist/passes/PingPongComputePass.js.map +1 -0
- package/dist/passes/ShaderPass.d.ts +1 -0
- package/dist/passes/ShaderPass.d.ts.map +1 -0
- package/dist/passes/ShaderPass.js +41 -37
- package/dist/passes/ShaderPass.js.map +1 -0
- package/dist/passes/index.d.ts +3 -0
- package/dist/passes/index.d.ts.map +1 -0
- package/dist/passes/index.js +6 -3
- package/dist/react/FragCanvas.d.ts +3 -2
- package/dist/react/FragCanvas.d.ts.map +1 -0
- package/dist/react/FragCanvas.js +234 -211
- package/dist/react/FragCanvas.js.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.js +200 -14
- package/dist/react/MotionGPUErrorOverlay.js.map +1 -0
- package/dist/react/Portal.d.ts +1 -0
- package/dist/react/Portal.d.ts.map +1 -0
- package/dist/react/Portal.js +18 -21
- package/dist/react/Portal.js.map +1 -0
- package/dist/react/advanced.d.ts +1 -0
- package/dist/react/advanced.d.ts.map +1 -0
- package/dist/react/advanced.js +14 -6
- package/dist/react/frame-context.d.ts +1 -0
- package/dist/react/frame-context.d.ts.map +1 -0
- package/dist/react/frame-context.js +88 -94
- package/dist/react/frame-context.js.map +1 -0
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +12 -9
- package/dist/react/motiongpu-context.d.ts +1 -0
- package/dist/react/motiongpu-context.d.ts.map +1 -0
- package/dist/react/motiongpu-context.js +18 -15
- package/dist/react/motiongpu-context.js.map +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/react/use-motiongpu-user-context.js +83 -82
- package/dist/react/use-motiongpu-user-context.js.map +1 -0
- package/dist/react/use-texture.d.ts +1 -0
- package/dist/react/use-texture.d.ts.map +1 -0
- package/dist/react/use-texture.js +132 -152
- package/dist/react/use-texture.js.map +1 -0
- package/dist/svelte/FragCanvas.svelte +2 -2
- package/dist/svelte/FragCanvas.svelte.d.ts +3 -2
- package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte +137 -7
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -0
- package/dist/svelte/Portal.svelte.d.ts +1 -0
- package/dist/svelte/Portal.svelte.d.ts.map +1 -0
- package/dist/svelte/advanced.d.ts +1 -0
- package/dist/svelte/advanced.d.ts.map +1 -0
- package/dist/svelte/advanced.js +13 -6
- package/dist/svelte/frame-context.d.ts +1 -0
- package/dist/svelte/frame-context.d.ts.map +1 -0
- package/dist/svelte/frame-context.js +27 -27
- package/dist/svelte/frame-context.js.map +1 -0
- package/dist/svelte/index.d.ts +6 -2
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +12 -9
- package/dist/svelte/motiongpu-context.d.ts +1 -0
- package/dist/svelte/motiongpu-context.d.ts.map +1 -0
- package/dist/svelte/motiongpu-context.js +24 -21
- package/dist/svelte/motiongpu-context.js.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.js +69 -70
- package/dist/svelte/use-motiongpu-user-context.js.map +1 -0
- package/dist/svelte/use-texture.d.ts +1 -0
- package/dist/svelte/use-texture.d.ts.map +1 -0
- package/dist/svelte/use-texture.js +125 -147
- package/dist/svelte/use-texture.js.map +1 -0
- package/package.json +12 -7
- package/src/lib/advanced.ts +6 -0
- package/src/lib/core/advanced.ts +12 -0
- package/src/lib/core/compute-shader.ts +326 -0
- package/src/lib/core/current-value.ts +64 -0
- package/src/lib/core/error-diagnostics.ts +236 -0
- package/src/lib/core/error-report.ts +535 -0
- package/src/lib/core/frame-registry.ts +1190 -0
- package/src/lib/core/index.ts +94 -0
- package/src/lib/core/material-preprocess.ts +295 -0
- package/src/lib/core/material.ts +748 -0
- package/src/lib/core/recompile-policy.ts +31 -0
- package/src/lib/core/render-graph.ts +173 -0
- package/src/lib/core/render-targets.ts +107 -0
- package/src/lib/core/renderer.ts +2161 -0
- package/src/lib/core/runtime-loop.ts +537 -0
- package/src/lib/core/scheduler-helpers.ts +136 -0
- package/src/lib/core/shader.ts +301 -0
- package/src/lib/core/storage-buffers.ts +142 -0
- package/src/lib/core/texture-loader.ts +482 -0
- package/src/lib/core/textures.ts +257 -0
- package/src/lib/core/types.ts +743 -0
- package/src/lib/core/uniforms.ts +282 -0
- package/src/lib/index.ts +6 -0
- package/src/lib/passes/BlitPass.ts +54 -0
- package/src/lib/passes/ComputePass.ts +136 -0
- package/src/lib/passes/CopyPass.ts +80 -0
- package/src/lib/passes/FullscreenPass.ts +173 -0
- package/src/lib/passes/PingPongComputePass.ts +180 -0
- package/src/lib/passes/ShaderPass.ts +89 -0
- package/src/lib/passes/index.ts +9 -0
- package/src/lib/react/FragCanvas.tsx +345 -0
- package/src/lib/react/MotionGPUErrorOverlay.tsx +524 -0
- package/src/lib/react/Portal.tsx +34 -0
- package/src/lib/react/advanced.ts +36 -0
- package/src/lib/react/frame-context.ts +169 -0
- package/src/lib/react/index.ts +68 -0
- package/src/lib/react/motiongpu-context.ts +88 -0
- package/src/lib/react/use-motiongpu-user-context.ts +186 -0
- package/src/lib/react/use-texture.ts +233 -0
- package/src/lib/svelte/FragCanvas.svelte +249 -0
- package/src/lib/svelte/MotionGPUErrorOverlay.svelte +512 -0
- package/src/lib/svelte/Portal.svelte +31 -0
- package/src/lib/svelte/advanced.ts +32 -0
- package/src/lib/svelte/frame-context.ts +87 -0
- package/src/lib/svelte/index.ts +68 -0
- package/src/lib/svelte/motiongpu-context.ts +97 -0
- package/src/lib/svelte/use-motiongpu-user-context.ts +145 -0
- package/src/lib/svelte/use-texture.ts +232 -0
package/README.md
CHANGED
|
@@ -80,6 +80,10 @@ Motion GPU follows a simple three-step flow:
|
|
|
80
80
|
- `BlitPass`
|
|
81
81
|
- `CopyPass`
|
|
82
82
|
|
|
83
|
+
- GPU compute passes:
|
|
84
|
+
- `ComputePass` — single-dispatch GPU compute workloads
|
|
85
|
+
- `PingPongComputePass` — iterative multi-step simulations with texture A/B alternation
|
|
86
|
+
|
|
83
87
|
- Named render targets for multi-pass pipelines
|
|
84
88
|
- Structured error normalization with built-in overlay UI and custom renderer support
|
|
85
89
|
- Advanced runtime API for namespaced shared user context and scheduler presets
|
|
@@ -100,6 +104,8 @@ Motion GPU follows a simple three-step flow:
|
|
|
100
104
|
- `ShaderPass`
|
|
101
105
|
- `BlitPass`
|
|
102
106
|
- `CopyPass`
|
|
107
|
+
- `ComputePass`
|
|
108
|
+
- `PingPongComputePass`
|
|
103
109
|
|
|
104
110
|
Also exports runtime/core types:
|
|
105
111
|
|
|
@@ -132,6 +138,8 @@ Also exports runtime/core types:
|
|
|
132
138
|
- `ShaderPass`
|
|
133
139
|
- `BlitPass`
|
|
134
140
|
- `CopyPass`
|
|
141
|
+
- `ComputePass`
|
|
142
|
+
- `PingPongComputePass`
|
|
135
143
|
|
|
136
144
|
Also exports runtime/core types:
|
|
137
145
|
|
|
@@ -167,6 +175,8 @@ Also exports runtime/core types:
|
|
|
167
175
|
- `ShaderPass`
|
|
168
176
|
- `BlitPass`
|
|
169
177
|
- `CopyPass`
|
|
178
|
+
- `ComputePass`
|
|
179
|
+
- `PingPongComputePass`
|
|
170
180
|
|
|
171
181
|
`@motion-core/motion-gpu/advanced` (and explicit alias `@motion-core/motion-gpu/core/advanced`) re-exports core plus:
|
|
172
182
|
|
|
@@ -298,6 +308,84 @@ export function Runtime() {
|
|
|
298
308
|
|
|
299
309
|
---
|
|
300
310
|
|
|
311
|
+
## 3. Add a GPU compute pass
|
|
312
|
+
|
|
313
|
+
```svelte
|
|
314
|
+
<!-- App.svelte -->
|
|
315
|
+
<script lang="ts">
|
|
316
|
+
import { FragCanvas, defineMaterial, ComputePass } from '@motion-core/motion-gpu/svelte';
|
|
317
|
+
import Runtime from './Runtime.svelte';
|
|
318
|
+
|
|
319
|
+
const material = defineMaterial({
|
|
320
|
+
fragment: `
|
|
321
|
+
fn frag(uv: vec2f) -> vec4f {
|
|
322
|
+
let idx = u32(uv.x * 255.0);
|
|
323
|
+
let particle = particles[idx];
|
|
324
|
+
return vec4f(particle.rgb, 1.0);
|
|
325
|
+
}
|
|
326
|
+
`,
|
|
327
|
+
storageBuffers: {
|
|
328
|
+
particles: { size: 4096, type: 'array<vec4f>', access: 'read-write' }
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
const simulate = new ComputePass({
|
|
333
|
+
compute: `
|
|
334
|
+
@compute @workgroup_size(64)
|
|
335
|
+
fn compute(@builtin(global_invocation_id) id: vec3u) {
|
|
336
|
+
let i = id.x;
|
|
337
|
+
let t = motiongpuFrame.time;
|
|
338
|
+
particles[i] = vec4f(sin(t + f32(i)), cos(t + f32(i)), 0.0, 1.0);
|
|
339
|
+
}
|
|
340
|
+
`,
|
|
341
|
+
dispatch: [16]
|
|
342
|
+
});
|
|
343
|
+
</script>
|
|
344
|
+
|
|
345
|
+
<FragCanvas {material} passes={[simulate]}>
|
|
346
|
+
<Runtime />
|
|
347
|
+
</FragCanvas>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
import { FragCanvas, defineMaterial, ComputePass } from '@motion-core/motion-gpu/react';
|
|
352
|
+
|
|
353
|
+
const material = defineMaterial({
|
|
354
|
+
fragment: `
|
|
355
|
+
fn frag(uv: vec2f) -> vec4f {
|
|
356
|
+
let idx = u32(uv.x * 255.0);
|
|
357
|
+
let particle = particles[idx];
|
|
358
|
+
return vec4f(particle.rgb, 1.0);
|
|
359
|
+
}
|
|
360
|
+
`,
|
|
361
|
+
storageBuffers: {
|
|
362
|
+
particles: { size: 4096, type: 'array<vec4f>', access: 'read-write' }
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const simulate = new ComputePass({
|
|
367
|
+
compute: `
|
|
368
|
+
@compute @workgroup_size(64)
|
|
369
|
+
fn compute(@builtin(global_invocation_id) id: vec3u) {
|
|
370
|
+
let i = id.x;
|
|
371
|
+
let t = motiongpuFrame.time;
|
|
372
|
+
particles[i] = vec4f(sin(t + f32(i)), cos(t + f32(i)), 0.0, 1.0);
|
|
373
|
+
}
|
|
374
|
+
`,
|
|
375
|
+
dispatch: [16]
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
export function App() {
|
|
379
|
+
return (
|
|
380
|
+
<div style={{ width: '100vw', height: '100vh' }}>
|
|
381
|
+
<FragCanvas material={material} passes={[simulate]} />
|
|
382
|
+
</div>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
301
389
|
# Core Runtime Model
|
|
302
390
|
|
|
303
391
|
## Material Phase (compile-time contract)
|
|
@@ -309,6 +397,7 @@ export function Runtime() {
|
|
|
309
397
|
- Texture declarations
|
|
310
398
|
- Compile-time `defines`
|
|
311
399
|
- Shader `includes`
|
|
400
|
+
- Storage buffer declarations
|
|
312
401
|
|
|
313
402
|
A deterministic material signature is generated from resolved shader/layout metadata.
|
|
314
403
|
|
|
@@ -320,6 +409,8 @@ Inside `useFrame(...)` callbacks you update per-frame values:
|
|
|
320
409
|
|
|
321
410
|
- `state.setUniform(name, value)`
|
|
322
411
|
- `state.setTexture(name, value)`
|
|
412
|
+
- `state.writeStorageBuffer(name, data, { offset? })`
|
|
413
|
+
- `state.readStorageBuffer(name)` — returns `Promise<ArrayBuffer>`
|
|
323
414
|
- `state.invalidate(token?)`
|
|
324
415
|
- `state.advance()`
|
|
325
416
|
|
|
@@ -367,6 +458,14 @@ fn shade(inputColor: vec4f, uv: vec2f) -> vec4f
|
|
|
367
458
|
|
|
368
459
|
8. `maxDelta` and profiling window must be finite and greater than `0`.
|
|
369
460
|
|
|
461
|
+
9. `ComputePass` shader must contain `@compute @workgroup_size(...)` and a `fn compute(...)` entrypoint with a `@builtin(global_invocation_id)` parameter.
|
|
462
|
+
|
|
463
|
+
10. `PingPongComputePass` `iterations` must be `>= 1`. The `target` must reference a texture declared with `storage: true` and explicit `width`/`height`.
|
|
464
|
+
|
|
465
|
+
11. Compute passes do not participate in render pass slot routing (no `input`/`output`/`needsSwap`).
|
|
466
|
+
|
|
467
|
+
12. Storage buffer `size` must be `> 0` and a multiple of 4. All storage buffers must be declared in `defineMaterial({ storageBuffers })`.
|
|
468
|
+
|
|
370
469
|
---
|
|
371
470
|
|
|
372
471
|
# Pipeline Rebuild Rules
|
package/dist/advanced.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../src/lib/advanced.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,oBAAoB,CAAC"}
|
package/dist/advanced.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { defineMaterial, resolveMaterial } from "./core/material.js";
|
|
2
|
+
import { toMotionGPUErrorReport } from "./core/error-report.js";
|
|
3
|
+
import { createCurrentWritable } from "./core/current-value.js";
|
|
4
|
+
import { createFrameRegistry } from "./core/frame-registry.js";
|
|
5
|
+
import { createMotionGPURuntimeLoop } from "./core/runtime-loop.js";
|
|
6
|
+
import { loadTexturesFromUrls } from "./core/texture-loader.js";
|
|
7
|
+
import { BlitPass } from "./passes/BlitPass.js";
|
|
8
|
+
import { CopyPass } from "./passes/CopyPass.js";
|
|
9
|
+
import { ShaderPass } from "./passes/ShaderPass.js";
|
|
10
|
+
import { ComputePass } from "./passes/ComputePass.js";
|
|
11
|
+
import { PingPongComputePass } from "./passes/PingPongComputePass.js";
|
|
12
|
+
import { applySchedulerPreset, captureSchedulerDebugSnapshot } from "./core/scheduler-helpers.js";
|
|
13
|
+
import "./core/advanced.js";
|
|
14
|
+
export { BlitPass, ComputePass, CopyPass, PingPongComputePass, ShaderPass, applySchedulerPreset, captureSchedulerDebugSnapshot, createCurrentWritable, createFrameRegistry, createMotionGPURuntimeLoop, defineMaterial, loadTexturesFromUrls, resolveMaterial, toMotionGPUErrorReport };
|
package/dist/core/advanced.d.ts
CHANGED
|
@@ -4,3 +4,4 @@
|
|
|
4
4
|
export * from './index.js';
|
|
5
5
|
export { applySchedulerPreset, captureSchedulerDebugSnapshot } from './scheduler-helpers.js';
|
|
6
6
|
export type { ApplySchedulerPresetOptions, MotionGPUScheduler, SchedulerDebugSnapshot, SchedulerPreset, SchedulerPresetConfig } from './scheduler-helpers.js';
|
|
7
|
+
//# sourceMappingURL=advanced.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../../src/lib/core/advanced.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AAC7F,YAAY,EACX,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,MAAM,wBAAwB,CAAC"}
|
package/dist/core/advanced.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { defineMaterial, resolveMaterial } from "./material.js";
|
|
2
|
+
import { toMotionGPUErrorReport } from "./error-report.js";
|
|
3
|
+
import { createCurrentWritable } from "./current-value.js";
|
|
4
|
+
import { createFrameRegistry } from "./frame-registry.js";
|
|
5
|
+
import { createMotionGPURuntimeLoop } from "./runtime-loop.js";
|
|
6
|
+
import { loadTexturesFromUrls } from "./texture-loader.js";
|
|
7
|
+
import { BlitPass } from "../passes/BlitPass.js";
|
|
8
|
+
import { CopyPass } from "../passes/CopyPass.js";
|
|
9
|
+
import { ShaderPass } from "../passes/ShaderPass.js";
|
|
10
|
+
import { ComputePass } from "../passes/ComputePass.js";
|
|
11
|
+
import { PingPongComputePass } from "../passes/PingPongComputePass.js";
|
|
12
|
+
import "./index.js";
|
|
13
|
+
import { applySchedulerPreset, captureSchedulerDebugSnapshot } from "./scheduler-helpers.js";
|
|
14
|
+
export { BlitPass, ComputePass, CopyPass, PingPongComputePass, ShaderPass, applySchedulerPreset, captureSchedulerDebugSnapshot, createCurrentWritable, createFrameRegistry, createMotionGPURuntimeLoop, defineMaterial, loadTexturesFromUrls, resolveMaterial, toMotionGPUErrorReport };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/// <reference types="@webgpu/types" />
|
|
2
|
+
import type { StorageBufferAccess, StorageBufferType, UniformLayout } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Regex contract for compute entrypoint.
|
|
5
|
+
* Matches: @compute @workgroup_size(...) fn compute(
|
|
6
|
+
* with @builtin(global_invocation_id) parameter.
|
|
7
|
+
*/
|
|
8
|
+
export declare const COMPUTE_ENTRY_CONTRACT: RegExp;
|
|
9
|
+
/**
|
|
10
|
+
* Validates compute shader user code matches the compute contract.
|
|
11
|
+
*
|
|
12
|
+
* @param compute - User compute shader WGSL source.
|
|
13
|
+
* @throws {Error} When shader does not match the compute contract.
|
|
14
|
+
*/
|
|
15
|
+
export declare function assertComputeContract(compute: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Extracts @workgroup_size values from WGSL compute shader.
|
|
18
|
+
*
|
|
19
|
+
* @param compute - Validated compute shader source.
|
|
20
|
+
* @returns Tuple [x, y, z] with defaults of 1 for omitted dimensions.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractWorkgroupSize(compute: string): [number, number, number];
|
|
23
|
+
/**
|
|
24
|
+
* Builds storage buffer binding declarations for compute shader.
|
|
25
|
+
*
|
|
26
|
+
* @param storageBufferKeys - Sorted buffer keys.
|
|
27
|
+
* @param definitions - Type/access definitions per key.
|
|
28
|
+
* @param groupIndex - Bind group index for storage buffers.
|
|
29
|
+
* @returns WGSL binding declaration string.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildComputeStorageBufferBindings(storageBufferKeys: string[], definitions: Record<string, {
|
|
32
|
+
type: StorageBufferType;
|
|
33
|
+
access: StorageBufferAccess;
|
|
34
|
+
}>, groupIndex: number): string;
|
|
35
|
+
/**
|
|
36
|
+
* Builds storage texture binding declarations for compute shader.
|
|
37
|
+
*
|
|
38
|
+
* @param storageTextureKeys - Sorted storage texture keys.
|
|
39
|
+
* @param definitions - Format definitions per key.
|
|
40
|
+
* @param groupIndex - Bind group index for storage textures.
|
|
41
|
+
* @returns WGSL binding declaration string.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildComputeStorageTextureBindings(storageTextureKeys: string[], definitions: Record<string, {
|
|
44
|
+
format: GPUTextureFormat;
|
|
45
|
+
}>, groupIndex: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* Maps storage texture format to sampled texture scalar type for `texture_2d<T>`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function storageTextureSampleScalarType(format: GPUTextureFormat): 'f32' | 'u32' | 'i32';
|
|
50
|
+
/**
|
|
51
|
+
* Assembles compute shader WGSL for ping-pong workflows.
|
|
52
|
+
*
|
|
53
|
+
* Exposes two generated bindings under group(2):
|
|
54
|
+
* - `${target}A`: sampled read texture (`texture_2d<T>`)
|
|
55
|
+
* - `${target}B`: storage write texture (`texture_storage_2d<format, write>`)
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildPingPongComputeShaderSource(options: {
|
|
58
|
+
compute: string;
|
|
59
|
+
uniformLayout: UniformLayout;
|
|
60
|
+
storageBufferKeys: string[];
|
|
61
|
+
storageBufferDefinitions: Record<string, {
|
|
62
|
+
type: StorageBufferType;
|
|
63
|
+
access: StorageBufferAccess;
|
|
64
|
+
}>;
|
|
65
|
+
target: string;
|
|
66
|
+
targetFormat: GPUTextureFormat;
|
|
67
|
+
}): string;
|
|
68
|
+
/**
|
|
69
|
+
* Assembles full compute shader WGSL with preamble.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Compute shader build options.
|
|
72
|
+
* @returns Complete WGSL source for compute stage.
|
|
73
|
+
*/
|
|
74
|
+
export declare function buildComputeShaderSource(options: {
|
|
75
|
+
compute: string;
|
|
76
|
+
uniformLayout: UniformLayout;
|
|
77
|
+
storageBufferKeys: string[];
|
|
78
|
+
storageBufferDefinitions: Record<string, {
|
|
79
|
+
type: StorageBufferType;
|
|
80
|
+
access: StorageBufferAccess;
|
|
81
|
+
}>;
|
|
82
|
+
storageTextureKeys: string[];
|
|
83
|
+
storageTextureDefinitions: Record<string, {
|
|
84
|
+
format: GPUTextureFormat;
|
|
85
|
+
}>;
|
|
86
|
+
}): string;
|
|
87
|
+
//# sourceMappingURL=compute-shader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-shader.d.ts","sourceRoot":"","sources":["../../src/lib/core/compute-shader.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAExF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAA+D,CAAC;AA+DnG;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAc3D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAc9E;AA2BD;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAChD,iBAAiB,EAAE,MAAM,EAAE,EAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAC,EACrF,UAAU,EAAE,MAAM,GAChB,MAAM,CAyBR;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CACjD,kBAAkB,EAAE,MAAM,EAAE,EAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,EACzD,UAAU,EAAE,MAAM,GAChB,MAAM,CAwBR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,gBAAgB,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAS9F;AAED;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAC/B,MAAM,EACN;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAE,CACxD,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,gBAAgB,CAAC;CAC/B,GAAG,MAAM,CA8BT;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,aAAa,CAAC;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAC/B,MAAM,EACN;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAE,CACxD,CAAC;IACF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC;CACxE,GAAG,MAAM,CA8BT"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
//#region src/lib/core/compute-shader.ts
|
|
2
|
+
/**
|
|
3
|
+
* Regex contract for compute entrypoint.
|
|
4
|
+
* Matches: @compute @workgroup_size(...) fn compute(
|
|
5
|
+
* with @builtin(global_invocation_id) parameter.
|
|
6
|
+
*/
|
|
7
|
+
var COMPUTE_ENTRY_CONTRACT = /@compute\s+@workgroup_size\s*\([^)]+\)\s*fn\s+compute\s*\(/;
|
|
8
|
+
/**
|
|
9
|
+
* Regex to extract @workgroup_size values.
|
|
10
|
+
*/
|
|
11
|
+
var WORKGROUP_SIZE_PATTERN = /@workgroup_size\s*\(\s*(\d+)(?:\s*,\s*(\d+))?(?:\s*,\s*(\d+))?\s*\)/;
|
|
12
|
+
/**
|
|
13
|
+
* Regex to verify @builtin(global_invocation_id) parameter.
|
|
14
|
+
*/
|
|
15
|
+
var GLOBAL_INVOCATION_ID_PATTERN = /@builtin\s*\(\s*global_invocation_id\s*\)/;
|
|
16
|
+
var WORKGROUP_DIMENSION_MIN = 1;
|
|
17
|
+
var WORKGROUP_DIMENSION_MAX = 65535;
|
|
18
|
+
function extractComputeParamList(compute) {
|
|
19
|
+
const computeFnIndex = compute.indexOf("fn compute");
|
|
20
|
+
if (computeFnIndex === -1) return null;
|
|
21
|
+
const openParenIndex = compute.indexOf("(", computeFnIndex);
|
|
22
|
+
if (openParenIndex === -1) return null;
|
|
23
|
+
let depth = 0;
|
|
24
|
+
for (let index = openParenIndex; index < compute.length; index += 1) {
|
|
25
|
+
const char = compute[index];
|
|
26
|
+
if (char === "(") {
|
|
27
|
+
depth += 1;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (char === ")") {
|
|
31
|
+
depth -= 1;
|
|
32
|
+
if (depth === 0) return compute.slice(openParenIndex + 1, index);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function assertWorkgroupDimension(value) {
|
|
38
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < WORKGROUP_DIMENSION_MIN || value > WORKGROUP_DIMENSION_MAX) throw new Error(`@workgroup_size dimensions must be integers in range ${WORKGROUP_DIMENSION_MIN}-${WORKGROUP_DIMENSION_MAX}, got ${value}.`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Default uniform field used when no custom uniforms are provided in compute.
|
|
42
|
+
*/
|
|
43
|
+
var DEFAULT_UNIFORM_FIELD = "motiongpu_unused: vec4f,";
|
|
44
|
+
/**
|
|
45
|
+
* Validates compute shader user code matches the compute contract.
|
|
46
|
+
*
|
|
47
|
+
* @param compute - User compute shader WGSL source.
|
|
48
|
+
* @throws {Error} When shader does not match the compute contract.
|
|
49
|
+
*/
|
|
50
|
+
function assertComputeContract(compute) {
|
|
51
|
+
if (!COMPUTE_ENTRY_CONTRACT.test(compute)) throw new Error("Compute shader must declare `@compute @workgroup_size(...) fn compute(...)`. Ensure the function is named `compute` and includes @compute and @workgroup_size annotations.");
|
|
52
|
+
const params = extractComputeParamList(compute);
|
|
53
|
+
if (!params || !GLOBAL_INVOCATION_ID_PATTERN.test(params)) throw new Error("Compute shader must include a `@builtin(global_invocation_id)` parameter.");
|
|
54
|
+
extractWorkgroupSize(compute);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Extracts @workgroup_size values from WGSL compute shader.
|
|
58
|
+
*
|
|
59
|
+
* @param compute - Validated compute shader source.
|
|
60
|
+
* @returns Tuple [x, y, z] with defaults of 1 for omitted dimensions.
|
|
61
|
+
*/
|
|
62
|
+
function extractWorkgroupSize(compute) {
|
|
63
|
+
const match = compute.match(WORKGROUP_SIZE_PATTERN);
|
|
64
|
+
if (!match) throw new Error("Could not extract @workgroup_size from compute shader source.");
|
|
65
|
+
const x = Number.parseInt(match[1] ?? "1", 10);
|
|
66
|
+
const y = Number.parseInt(match[2] ?? "1", 10);
|
|
67
|
+
const z = Number.parseInt(match[3] ?? "1", 10);
|
|
68
|
+
assertWorkgroupDimension(x);
|
|
69
|
+
assertWorkgroupDimension(y);
|
|
70
|
+
assertWorkgroupDimension(z);
|
|
71
|
+
return [
|
|
72
|
+
x,
|
|
73
|
+
y,
|
|
74
|
+
z
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Maps StorageBufferAccess to WGSL var qualifier.
|
|
79
|
+
*/
|
|
80
|
+
function toWgslAccessMode(access) {
|
|
81
|
+
switch (access) {
|
|
82
|
+
case "read": return "read";
|
|
83
|
+
case "read-write": return "read_write";
|
|
84
|
+
default: throw new Error(`Unsupported storage buffer access mode "${String(access)}".`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Builds WGSL struct fields for uniforms used in compute shader preamble.
|
|
89
|
+
*/
|
|
90
|
+
function buildUniformStructForCompute(layout) {
|
|
91
|
+
if (layout.entries.length === 0) return DEFAULT_UNIFORM_FIELD;
|
|
92
|
+
return layout.entries.map((entry) => `${entry.name}: ${entry.type},`).join("\n ");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Builds storage buffer binding declarations for compute shader.
|
|
96
|
+
*
|
|
97
|
+
* @param storageBufferKeys - Sorted buffer keys.
|
|
98
|
+
* @param definitions - Type/access definitions per key.
|
|
99
|
+
* @param groupIndex - Bind group index for storage buffers.
|
|
100
|
+
* @returns WGSL binding declaration string.
|
|
101
|
+
*/
|
|
102
|
+
function buildComputeStorageBufferBindings(storageBufferKeys, definitions, groupIndex) {
|
|
103
|
+
if (storageBufferKeys.length === 0) return "";
|
|
104
|
+
const declarations = [];
|
|
105
|
+
for (let index = 0; index < storageBufferKeys.length; index += 1) {
|
|
106
|
+
const key = storageBufferKeys[index];
|
|
107
|
+
if (key === void 0) continue;
|
|
108
|
+
const definition = definitions[key];
|
|
109
|
+
if (!definition) continue;
|
|
110
|
+
const accessMode = toWgslAccessMode(definition.access);
|
|
111
|
+
declarations.push(`@group(${groupIndex}) @binding(${index}) var<storage, ${accessMode}> ${key}: ${definition.type};`);
|
|
112
|
+
}
|
|
113
|
+
return declarations.join("\n");
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Builds storage texture binding declarations for compute shader.
|
|
117
|
+
*
|
|
118
|
+
* @param storageTextureKeys - Sorted storage texture keys.
|
|
119
|
+
* @param definitions - Format definitions per key.
|
|
120
|
+
* @param groupIndex - Bind group index for storage textures.
|
|
121
|
+
* @returns WGSL binding declaration string.
|
|
122
|
+
*/
|
|
123
|
+
function buildComputeStorageTextureBindings(storageTextureKeys, definitions, groupIndex) {
|
|
124
|
+
if (storageTextureKeys.length === 0) return "";
|
|
125
|
+
const declarations = [];
|
|
126
|
+
for (let index = 0; index < storageTextureKeys.length; index += 1) {
|
|
127
|
+
const key = storageTextureKeys[index];
|
|
128
|
+
if (key === void 0) continue;
|
|
129
|
+
const definition = definitions[key];
|
|
130
|
+
if (!definition) continue;
|
|
131
|
+
declarations.push(`@group(${groupIndex}) @binding(${index}) var ${key}: texture_storage_2d<${definition.format}, write>;`);
|
|
132
|
+
}
|
|
133
|
+
return declarations.join("\n");
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Maps storage texture format to sampled texture scalar type for `texture_2d<T>`.
|
|
137
|
+
*/
|
|
138
|
+
function storageTextureSampleScalarType(format) {
|
|
139
|
+
const normalized = String(format).toLowerCase();
|
|
140
|
+
if (normalized.endsWith("uint")) return "u32";
|
|
141
|
+
if (normalized.endsWith("sint")) return "i32";
|
|
142
|
+
return "f32";
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Assembles compute shader WGSL for ping-pong workflows.
|
|
146
|
+
*
|
|
147
|
+
* Exposes two generated bindings under group(2):
|
|
148
|
+
* - `${target}A`: sampled read texture (`texture_2d<T>`)
|
|
149
|
+
* - `${target}B`: storage write texture (`texture_storage_2d<format, write>`)
|
|
150
|
+
*/
|
|
151
|
+
function buildPingPongComputeShaderSource(options) {
|
|
152
|
+
const uniformFields = buildUniformStructForCompute(options.uniformLayout);
|
|
153
|
+
const storageBufferBindings = buildComputeStorageBufferBindings(options.storageBufferKeys, options.storageBufferDefinitions, 1);
|
|
154
|
+
const sampledType = storageTextureSampleScalarType(options.targetFormat);
|
|
155
|
+
const pingPongTextureBindings = [`@group(2) @binding(0) var ${options.target}A: texture_2d<${sampledType}>;`, `@group(2) @binding(1) var ${options.target}B: texture_storage_2d<${options.targetFormat}, write>;`].join("\n");
|
|
156
|
+
return `struct MotionGPUFrame {
|
|
157
|
+
time: f32,
|
|
158
|
+
delta: f32,
|
|
159
|
+
resolution: vec2f,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
struct MotionGPUUniforms {
|
|
163
|
+
${uniformFields}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
@group(0) @binding(0) var<uniform> motiongpuFrame: MotionGPUFrame;
|
|
167
|
+
@group(0) @binding(1) var<uniform> motiongpuUniforms: MotionGPUUniforms;
|
|
168
|
+
${storageBufferBindings ? "\n" + storageBufferBindings : ""}
|
|
169
|
+
${pingPongTextureBindings ? "\n" + pingPongTextureBindings : ""}
|
|
170
|
+
|
|
171
|
+
${options.compute}
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Assembles full compute shader WGSL with preamble.
|
|
176
|
+
*
|
|
177
|
+
* @param options - Compute shader build options.
|
|
178
|
+
* @returns Complete WGSL source for compute stage.
|
|
179
|
+
*/
|
|
180
|
+
function buildComputeShaderSource(options) {
|
|
181
|
+
const uniformFields = buildUniformStructForCompute(options.uniformLayout);
|
|
182
|
+
const storageBufferBindings = buildComputeStorageBufferBindings(options.storageBufferKeys, options.storageBufferDefinitions, 1);
|
|
183
|
+
const storageTextureBindings = buildComputeStorageTextureBindings(options.storageTextureKeys, options.storageTextureDefinitions, 2);
|
|
184
|
+
return `struct MotionGPUFrame {
|
|
185
|
+
time: f32,
|
|
186
|
+
delta: f32,
|
|
187
|
+
resolution: vec2f,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
struct MotionGPUUniforms {
|
|
191
|
+
${uniformFields}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
@group(0) @binding(0) var<uniform> motiongpuFrame: MotionGPUFrame;
|
|
195
|
+
@group(0) @binding(1) var<uniform> motiongpuUniforms: MotionGPUUniforms;
|
|
196
|
+
${storageBufferBindings ? "\n" + storageBufferBindings : ""}
|
|
197
|
+
${storageTextureBindings ? "\n" + storageTextureBindings : ""}
|
|
198
|
+
|
|
199
|
+
${options.compute}
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
export { COMPUTE_ENTRY_CONTRACT, assertComputeContract, buildComputeShaderSource, buildComputeStorageBufferBindings, buildComputeStorageTextureBindings, buildPingPongComputeShaderSource, extractWorkgroupSize, storageTextureSampleScalarType };
|
|
204
|
+
|
|
205
|
+
//# sourceMappingURL=compute-shader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-shader.js","names":[],"sources":["../../src/lib/core/compute-shader.ts"],"sourcesContent":["import type { StorageBufferAccess, StorageBufferType, UniformLayout } from './types.js';\n\n/**\n * Regex contract for compute entrypoint.\n * Matches: @compute @workgroup_size(...) fn compute(\n * with @builtin(global_invocation_id) parameter.\n */\nexport const COMPUTE_ENTRY_CONTRACT = /@compute\\s+@workgroup_size\\s*\\([^)]+\\)\\s*fn\\s+compute\\s*\\(/;\n\n/**\n * Regex to extract @workgroup_size values.\n */\nconst WORKGROUP_SIZE_PATTERN =\n\t/@workgroup_size\\s*\\(\\s*(\\d+)(?:\\s*,\\s*(\\d+))?(?:\\s*,\\s*(\\d+))?\\s*\\)/;\n\n/**\n * Regex to verify @builtin(global_invocation_id) parameter.\n */\nconst GLOBAL_INVOCATION_ID_PATTERN = /@builtin\\s*\\(\\s*global_invocation_id\\s*\\)/;\nconst WORKGROUP_DIMENSION_MIN = 1;\nconst WORKGROUP_DIMENSION_MAX = 65535;\n\nfunction extractComputeParamList(compute: string): string | null {\n\tconst computeFnIndex = compute.indexOf('fn compute');\n\tif (computeFnIndex === -1) {\n\t\treturn null;\n\t}\n\n\tconst openParenIndex = compute.indexOf('(', computeFnIndex);\n\tif (openParenIndex === -1) {\n\t\treturn null;\n\t}\n\n\tlet depth = 0;\n\tfor (let index = openParenIndex; index < compute.length; index += 1) {\n\t\tconst char = compute[index];\n\t\tif (char === '(') {\n\t\t\tdepth += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === ')') {\n\t\t\tdepth -= 1;\n\t\t\tif (depth === 0) {\n\t\t\t\treturn compute.slice(openParenIndex + 1, index);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction assertWorkgroupDimension(value: number): void {\n\tif (\n\t\t!Number.isFinite(value) ||\n\t\t!Number.isInteger(value) ||\n\t\tvalue < WORKGROUP_DIMENSION_MIN ||\n\t\tvalue > WORKGROUP_DIMENSION_MAX\n\t) {\n\t\tthrow new Error(\n\t\t\t`@workgroup_size dimensions must be integers in range ${WORKGROUP_DIMENSION_MIN}-${WORKGROUP_DIMENSION_MAX}, got ${value}.`\n\t\t);\n\t}\n}\n\n/**\n * Default uniform field used when no custom uniforms are provided in compute.\n */\nconst DEFAULT_UNIFORM_FIELD = 'motiongpu_unused: vec4f,';\n\n/**\n * Validates compute shader user code matches the compute contract.\n *\n * @param compute - User compute shader WGSL source.\n * @throws {Error} When shader does not match the compute contract.\n */\nexport function assertComputeContract(compute: string): void {\n\tif (!COMPUTE_ENTRY_CONTRACT.test(compute)) {\n\t\tthrow new Error(\n\t\t\t'Compute shader must declare `@compute @workgroup_size(...) fn compute(...)`. ' +\n\t\t\t\t'Ensure the function is named `compute` and includes @compute and @workgroup_size annotations.'\n\t\t);\n\t}\n\n\tconst params = extractComputeParamList(compute);\n\tif (!params || !GLOBAL_INVOCATION_ID_PATTERN.test(params)) {\n\t\tthrow new Error('Compute shader must include a `@builtin(global_invocation_id)` parameter.');\n\t}\n\n\textractWorkgroupSize(compute);\n}\n\n/**\n * Extracts @workgroup_size values from WGSL compute shader.\n *\n * @param compute - Validated compute shader source.\n * @returns Tuple [x, y, z] with defaults of 1 for omitted dimensions.\n */\nexport function extractWorkgroupSize(compute: string): [number, number, number] {\n\tconst match = compute.match(WORKGROUP_SIZE_PATTERN);\n\tif (!match) {\n\t\tthrow new Error('Could not extract @workgroup_size from compute shader source.');\n\t}\n\n\tconst x = Number.parseInt(match[1] ?? '1', 10);\n\tconst y = Number.parseInt(match[2] ?? '1', 10);\n\tconst z = Number.parseInt(match[3] ?? '1', 10);\n\tassertWorkgroupDimension(x);\n\tassertWorkgroupDimension(y);\n\tassertWorkgroupDimension(z);\n\n\treturn [x, y, z];\n}\n\n/**\n * Maps StorageBufferAccess to WGSL var qualifier.\n */\nfunction toWgslAccessMode(access: StorageBufferAccess): string {\n\tswitch (access) {\n\t\tcase 'read':\n\t\t\treturn 'read';\n\t\tcase 'read-write':\n\t\t\treturn 'read_write';\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported storage buffer access mode \"${String(access)}\".`);\n\t}\n}\n\n/**\n * Builds WGSL struct fields for uniforms used in compute shader preamble.\n */\nfunction buildUniformStructForCompute(layout: UniformLayout): string {\n\tif (layout.entries.length === 0) {\n\t\treturn DEFAULT_UNIFORM_FIELD;\n\t}\n\n\treturn layout.entries.map((entry) => `${entry.name}: ${entry.type},`).join('\\n\\t');\n}\n\n/**\n * Builds storage buffer binding declarations for compute shader.\n *\n * @param storageBufferKeys - Sorted buffer keys.\n * @param definitions - Type/access definitions per key.\n * @param groupIndex - Bind group index for storage buffers.\n * @returns WGSL binding declaration string.\n */\nexport function buildComputeStorageBufferBindings(\n\tstorageBufferKeys: string[],\n\tdefinitions: Record<string, { type: StorageBufferType; access: StorageBufferAccess }>,\n\tgroupIndex: number\n): string {\n\tif (storageBufferKeys.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst declarations: string[] = [];\n\n\tfor (let index = 0; index < storageBufferKeys.length; index += 1) {\n\t\tconst key = storageBufferKeys[index];\n\t\tif (key === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst definition = definitions[key];\n\t\tif (!definition) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst accessMode = toWgslAccessMode(definition.access);\n\t\tdeclarations.push(\n\t\t\t`@group(${groupIndex}) @binding(${index}) var<storage, ${accessMode}> ${key}: ${definition.type};`\n\t\t);\n\t}\n\n\treturn declarations.join('\\n');\n}\n\n/**\n * Builds storage texture binding declarations for compute shader.\n *\n * @param storageTextureKeys - Sorted storage texture keys.\n * @param definitions - Format definitions per key.\n * @param groupIndex - Bind group index for storage textures.\n * @returns WGSL binding declaration string.\n */\nexport function buildComputeStorageTextureBindings(\n\tstorageTextureKeys: string[],\n\tdefinitions: Record<string, { format: GPUTextureFormat }>,\n\tgroupIndex: number\n): string {\n\tif (storageTextureKeys.length === 0) {\n\t\treturn '';\n\t}\n\n\tconst declarations: string[] = [];\n\n\tfor (let index = 0; index < storageTextureKeys.length; index += 1) {\n\t\tconst key = storageTextureKeys[index];\n\t\tif (key === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst definition = definitions[key];\n\t\tif (!definition) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdeclarations.push(\n\t\t\t`@group(${groupIndex}) @binding(${index}) var ${key}: texture_storage_2d<${definition.format}, write>;`\n\t\t);\n\t}\n\n\treturn declarations.join('\\n');\n}\n\n/**\n * Maps storage texture format to sampled texture scalar type for `texture_2d<T>`.\n */\nexport function storageTextureSampleScalarType(format: GPUTextureFormat): 'f32' | 'u32' | 'i32' {\n\tconst normalized = String(format).toLowerCase();\n\tif (normalized.endsWith('uint')) {\n\t\treturn 'u32';\n\t}\n\tif (normalized.endsWith('sint')) {\n\t\treturn 'i32';\n\t}\n\treturn 'f32';\n}\n\n/**\n * Assembles compute shader WGSL for ping-pong workflows.\n *\n * Exposes two generated bindings under group(2):\n * - `${target}A`: sampled read texture (`texture_2d<T>`)\n * - `${target}B`: storage write texture (`texture_storage_2d<format, write>`)\n */\nexport function buildPingPongComputeShaderSource(options: {\n\tcompute: string;\n\tuniformLayout: UniformLayout;\n\tstorageBufferKeys: string[];\n\tstorageBufferDefinitions: Record<\n\t\tstring,\n\t\t{ type: StorageBufferType; access: StorageBufferAccess }\n\t>;\n\ttarget: string;\n\ttargetFormat: GPUTextureFormat;\n}): string {\n\tconst uniformFields = buildUniformStructForCompute(options.uniformLayout);\n\tconst storageBufferBindings = buildComputeStorageBufferBindings(\n\t\toptions.storageBufferKeys,\n\t\toptions.storageBufferDefinitions,\n\t\t1\n\t);\n\tconst sampledType = storageTextureSampleScalarType(options.targetFormat);\n\tconst pingPongTextureBindings = [\n\t\t`@group(2) @binding(0) var ${options.target}A: texture_2d<${sampledType}>;`,\n\t\t`@group(2) @binding(1) var ${options.target}B: texture_storage_2d<${options.targetFormat}, write>;`\n\t].join('\\n');\n\n\treturn `struct MotionGPUFrame {\n\ttime: f32,\n\tdelta: f32,\n\tresolution: vec2f,\n};\n\nstruct MotionGPUUniforms {\n\t${uniformFields}\n};\n\n@group(0) @binding(0) var<uniform> motiongpuFrame: MotionGPUFrame;\n@group(0) @binding(1) var<uniform> motiongpuUniforms: MotionGPUUniforms;\n${storageBufferBindings ? '\\n' + storageBufferBindings : ''}\n${pingPongTextureBindings ? '\\n' + pingPongTextureBindings : ''}\n\n${options.compute}\n`;\n}\n\n/**\n * Assembles full compute shader WGSL with preamble.\n *\n * @param options - Compute shader build options.\n * @returns Complete WGSL source for compute stage.\n */\nexport function buildComputeShaderSource(options: {\n\tcompute: string;\n\tuniformLayout: UniformLayout;\n\tstorageBufferKeys: string[];\n\tstorageBufferDefinitions: Record<\n\t\tstring,\n\t\t{ type: StorageBufferType; access: StorageBufferAccess }\n\t>;\n\tstorageTextureKeys: string[];\n\tstorageTextureDefinitions: Record<string, { format: GPUTextureFormat }>;\n}): string {\n\tconst uniformFields = buildUniformStructForCompute(options.uniformLayout);\n\tconst storageBufferBindings = buildComputeStorageBufferBindings(\n\t\toptions.storageBufferKeys,\n\t\toptions.storageBufferDefinitions,\n\t\t1\n\t);\n\tconst storageTextureBindings = buildComputeStorageTextureBindings(\n\t\toptions.storageTextureKeys,\n\t\toptions.storageTextureDefinitions,\n\t\t2\n\t);\n\n\treturn `struct MotionGPUFrame {\n\ttime: f32,\n\tdelta: f32,\n\tresolution: vec2f,\n};\n\nstruct MotionGPUUniforms {\n\t${uniformFields}\n};\n\n@group(0) @binding(0) var<uniform> motiongpuFrame: MotionGPUFrame;\n@group(0) @binding(1) var<uniform> motiongpuUniforms: MotionGPUUniforms;\n${storageBufferBindings ? '\\n' + storageBufferBindings : ''}\n${storageTextureBindings ? '\\n' + storageTextureBindings : ''}\n\n${options.compute}\n`;\n}\n"],"mappings":"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"}
|
|
@@ -21,3 +21,4 @@ export interface CurrentWritable<T> extends CurrentReadable<T> {
|
|
|
21
21
|
* Creates a writable value with immediate subscription semantics.
|
|
22
22
|
*/
|
|
23
23
|
export declare function createCurrentWritable<T>(initialValue: T, onChange?: (value: T) => void): CurrentWritable<T>;
|
|
24
|
+
//# sourceMappingURL=current-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-value.d.ts","sourceRoot":"","sources":["../../src/lib/core/current-value.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC7D,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACxB,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACtC,YAAY,EAAE,CAAC,EACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAC3B,eAAe,CAAC,CAAC,CAAC,CAmCpB"}
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
+
//#region src/lib/core/current-value.ts
|
|
1
2
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
update(updater) {
|
|
33
|
-
set(updater(current));
|
|
34
|
-
}
|
|
35
|
-
};
|
|
3
|
+
* Creates a writable value with immediate subscription semantics.
|
|
4
|
+
*/
|
|
5
|
+
function createCurrentWritable(initialValue, onChange) {
|
|
6
|
+
let current = initialValue;
|
|
7
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
8
|
+
const notify = (value) => {
|
|
9
|
+
for (const run of subscribers) run(value);
|
|
10
|
+
};
|
|
11
|
+
const set = (value) => {
|
|
12
|
+
if (Object.is(current, value)) return;
|
|
13
|
+
current = value;
|
|
14
|
+
notify(value);
|
|
15
|
+
onChange?.(value);
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
get current() {
|
|
19
|
+
return current;
|
|
20
|
+
},
|
|
21
|
+
subscribe(run) {
|
|
22
|
+
subscribers.add(run);
|
|
23
|
+
run(current);
|
|
24
|
+
return () => {
|
|
25
|
+
subscribers.delete(run);
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
set,
|
|
29
|
+
update(updater) {
|
|
30
|
+
set(updater(current));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
36
33
|
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createCurrentWritable };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=current-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-value.js","names":[],"sources":["../../src/lib/core/current-value.ts"],"sourcesContent":["/**\n * Minimal subscribe contract used by MotionGPU core.\n */\nexport interface Subscribable<T> {\n\tsubscribe: (run: (value: T) => void) => () => void;\n}\n\n/**\n * Readable value with synchronous access to the latest value.\n */\nexport interface CurrentReadable<T> extends Subscribable<T> {\n\treadonly current: T;\n}\n\n/**\n * Writable extension of {@link CurrentReadable}.\n */\nexport interface CurrentWritable<T> extends CurrentReadable<T> {\n\tset: (value: T) => void;\n\tupdate: (updater: (value: T) => T) => void;\n}\n\n/**\n * Creates a writable value with immediate subscription semantics.\n */\nexport function createCurrentWritable<T>(\n\tinitialValue: T,\n\tonChange?: (value: T) => void\n): CurrentWritable<T> {\n\tlet current = initialValue;\n\tconst subscribers = new Set<(value: T) => void>();\n\n\tconst notify = (value: T): void => {\n\t\tfor (const run of subscribers) {\n\t\t\trun(value);\n\t\t}\n\t};\n\n\tconst set = (value: T): void => {\n\t\tif (Object.is(current, value)) {\n\t\t\treturn;\n\t\t}\n\t\tcurrent = value;\n\t\tnotify(value);\n\t\tonChange?.(value);\n\t};\n\n\treturn {\n\t\tget current() {\n\t\t\treturn current;\n\t\t},\n\t\tsubscribe(run) {\n\t\t\tsubscribers.add(run);\n\t\t\trun(current);\n\t\t\treturn () => {\n\t\t\t\tsubscribers.delete(run);\n\t\t\t};\n\t\t},\n\t\tset,\n\t\tupdate(updater) {\n\t\t\tset(updater(current));\n\t\t}\n\t};\n}\n"],"mappings":";;;;AAyBA,SAAgB,sBACf,cACA,UACqB;CACrB,IAAI,UAAU;CACd,MAAM,8BAAc,IAAI,KAAyB;CAEjD,MAAM,UAAU,UAAmB;AAClC,OAAK,MAAM,OAAO,YACjB,KAAI,MAAM;;CAIZ,MAAM,OAAO,UAAmB;AAC/B,MAAI,OAAO,GAAG,SAAS,MAAM,CAC5B;AAED,YAAU;AACV,SAAO,MAAM;AACb,aAAW,MAAM;;AAGlB,QAAO;EACN,IAAI,UAAU;AACb,UAAO;;EAER,UAAU,KAAK;AACd,eAAY,IAAI,IAAI;AACpB,OAAI,QAAQ;AACZ,gBAAa;AACZ,gBAAY,OAAO,IAAI;;;EAGzB;EACA,OAAO,SAAS;AACf,OAAI,QAAQ,QAAQ,CAAC;;EAEtB"}
|
|
@@ -52,3 +52,4 @@ export declare function attachShaderCompilationDiagnostics(error: Error, payload
|
|
|
52
52
|
* Extracts structured diagnostics payload from unknown error value.
|
|
53
53
|
*/
|
|
54
54
|
export declare function getShaderCompilationDiagnostics(error: unknown): ShaderCompilationDiagnosticsPayload | null;
|
|
55
|
+
//# sourceMappingURL=error-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-diagnostics.d.ts","sourceRoot":"","sources":["../../src/lib/core/error-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD,IAAI,EAAE,oBAAoB,CAAC;IAC3B,WAAW,EAAE,2BAA2B,EAAE,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,cAAc,CAAC,EAAE,+BAA+B,CAAC;CACjD;AAkHD;;GAEG;AACH,wBAAgB,kCAAkC,CACjD,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,mCAAmC,GAC1C,KAAK,CAGP;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC9C,KAAK,EAAE,OAAO,GACZ,mCAAmC,GAAG,IAAI,CAwD5C"}
|