@motion-core/motion-gpu 0.1.0 → 0.3.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 +37 -11
- package/dist/advanced.d.ts +3 -11
- package/dist/advanced.js +3 -6
- package/dist/core/advanced.d.ts +6 -0
- package/dist/core/advanced.js +5 -0
- package/dist/core/current-value.d.ts +23 -0
- package/dist/core/current-value.js +36 -0
- package/dist/core/error-diagnostics.d.ts +15 -1
- package/dist/core/error-diagnostics.js +41 -1
- package/dist/core/error-report.d.ts +37 -0
- package/dist/core/error-report.js +62 -3
- package/dist/{frame-context.d.ts → core/frame-registry.d.ts} +3 -17
- package/dist/{frame-context.js → core/frame-registry.js} +2 -37
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.js +12 -0
- package/dist/core/material-preprocess.d.ts +1 -1
- package/dist/core/material-preprocess.js +1 -1
- package/dist/core/material.d.ts +4 -4
- package/dist/core/material.js +3 -3
- package/dist/core/recompile-policy.d.ts +1 -1
- package/dist/core/render-graph.d.ts +1 -1
- package/dist/core/render-targets.d.ts +1 -1
- package/dist/core/render-targets.js +1 -1
- package/dist/core/renderer.d.ts +11 -1
- package/dist/core/renderer.js +72 -10
- package/dist/core/runtime-loop.d.ts +34 -0
- package/dist/core/runtime-loop.js +365 -0
- package/dist/{advanced-scheduler.d.ts → core/scheduler-helpers.d.ts} +6 -2
- package/dist/core/shader.d.ts +2 -2
- package/dist/core/shader.js +1 -1
- package/dist/core/texture-loader.d.ts +1 -1
- package/dist/core/textures.d.ts +1 -1
- package/dist/core/textures.js +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/uniforms.d.ts +1 -1
- package/dist/index.d.ts +3 -14
- package/dist/index.js +3 -8
- package/dist/passes/BlitPass.d.ts +6 -27
- package/dist/passes/BlitPass.js +10 -121
- package/dist/passes/CopyPass.d.ts +1 -1
- package/dist/passes/CopyPass.js +1 -1
- package/dist/passes/FullscreenPass.d.ts +37 -0
- package/dist/passes/FullscreenPass.js +131 -0
- package/dist/passes/ShaderPass.d.ts +6 -26
- package/dist/passes/ShaderPass.js +10 -121
- package/dist/passes/index.d.ts +3 -3
- package/dist/passes/index.js +3 -3
- package/dist/svelte/FragCanvas.svelte +263 -0
- package/dist/{FragCanvas.svelte.d.ts → svelte/FragCanvas.svelte.d.ts} +5 -3
- package/dist/{MotionGPUErrorOverlay.svelte → svelte/MotionGPUErrorOverlay.svelte} +11 -20
- package/dist/{MotionGPUErrorOverlay.svelte.d.ts → svelte/MotionGPUErrorOverlay.svelte.d.ts} +1 -1
- package/dist/svelte/advanced.d.ts +11 -0
- package/dist/svelte/advanced.js +6 -0
- package/dist/svelte/frame-context.d.ts +14 -0
- package/dist/svelte/frame-context.js +32 -0
- package/dist/svelte/index.d.ts +15 -0
- package/dist/svelte/index.js +9 -0
- package/dist/{motiongpu-context.d.ts → svelte/motiongpu-context.d.ts} +5 -7
- package/dist/{use-motiongpu-user-context.d.ts → svelte/use-motiongpu-user-context.d.ts} +2 -2
- package/dist/{use-motiongpu-user-context.js → svelte/use-motiongpu-user-context.js} +1 -1
- package/dist/{use-texture.d.ts → svelte/use-texture.d.ts} +7 -2
- package/dist/{use-texture.js → svelte/use-texture.js} +9 -3
- package/package.json +25 -5
- package/dist/FragCanvas.svelte +0 -511
- package/dist/current-writable.d.ts +0 -31
- package/dist/current-writable.js +0 -27
- /package/dist/{advanced-scheduler.js → core/scheduler-helpers.js} +0 -0
- /package/dist/{Portal.svelte → svelte/Portal.svelte} +0 -0
- /package/dist/{Portal.svelte.d.ts → svelte/Portal.svelte.d.ts} +0 -0
- /package/dist/{motiongpu-context.js → svelte/motiongpu-context.js} +0 -0
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
**A tiny WebGPU runtime for writing Shadertoy-style fullscreen shaders in pure WGSL.**
|
|
14
14
|
|
|
15
|
-
`@motion-core/motion-gpu`
|
|
16
|
-
It provides a minimal runtime, scheduler, and render graph designed specifically for fragment-driven GPU programs.
|
|
15
|
+
`@motion-core/motion-gpu` ships a framework-agnostic core plus a Svelte 5 adapter for building fullscreen shader pipelines using WebGPU and WGSL.
|
|
16
|
+
It provides a minimal runtime loop, scheduler, and render graph designed specifically for fragment-driven GPU programs.
|
|
17
17
|
|
|
18
18
|
Unlike general-purpose 3D engines, Motion GPU focuses on a very narrow problem: **running fullscreen fragment shaders and multi-pass GPU pipelines**.
|
|
19
19
|
|
|
@@ -87,9 +87,9 @@ Motion GPU follows a simple three-step flow:
|
|
|
87
87
|
|
|
88
88
|
# Entrypoints
|
|
89
89
|
|
|
90
|
-
##
|
|
90
|
+
## Svelte adapter
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
`@motion-core/motion-gpu/svelte` exposes the runtime API for Svelte:
|
|
93
93
|
|
|
94
94
|
- `FragCanvas`
|
|
95
95
|
- `defineMaterial`
|
|
@@ -110,9 +110,7 @@ Also exports runtime/core types:
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Re-exports everything from root, plus:
|
|
113
|
+
`@motion-core/motion-gpu/svelte/advanced` re-exports everything above, plus:
|
|
116
114
|
|
|
117
115
|
- `useMotionGPUUserContext`
|
|
118
116
|
- `setMotionGPUUserContext`
|
|
@@ -121,9 +119,31 @@ Re-exports everything from root, plus:
|
|
|
121
119
|
|
|
122
120
|
---
|
|
123
121
|
|
|
122
|
+
## Framework-agnostic core
|
|
123
|
+
|
|
124
|
+
`@motion-core/motion-gpu` (and explicit alias `@motion-core/motion-gpu/core`) exposes adapter-building primitives:
|
|
125
|
+
|
|
126
|
+
- `defineMaterial`
|
|
127
|
+
- `resolveMaterial`
|
|
128
|
+
- `createCurrentWritable`
|
|
129
|
+
- `createFrameRegistry`
|
|
130
|
+
- `createMotionGPURuntimeLoop`
|
|
131
|
+
- `loadTexturesFromUrls`
|
|
132
|
+
- `toMotionGPUErrorReport`
|
|
133
|
+
- `ShaderPass`
|
|
134
|
+
- `BlitPass`
|
|
135
|
+
- `CopyPass`
|
|
136
|
+
|
|
137
|
+
`@motion-core/motion-gpu/advanced` (and explicit alias `@motion-core/motion-gpu/core/advanced`) re-exports core plus:
|
|
138
|
+
|
|
139
|
+
- `applySchedulerPreset`
|
|
140
|
+
- `captureSchedulerDebugSnapshot`
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
124
144
|
# Requirements
|
|
125
145
|
|
|
126
|
-
- Svelte 5 (
|
|
146
|
+
- Svelte 5 is required only for the Svelte adapter entrypoints (`/svelte`, `/svelte/advanced`)
|
|
127
147
|
- A browser/runtime with WebGPU support
|
|
128
148
|
- Secure context (`https://` or `localhost`)
|
|
129
149
|
|
|
@@ -137,6 +157,12 @@ npm i @motion-core/motion-gpu
|
|
|
137
157
|
|
|
138
158
|
---
|
|
139
159
|
|
|
160
|
+
# AI Documentation
|
|
161
|
+
|
|
162
|
+
MotionGPU documentation is also available for AI tools via [Context7](https://context7.com/motion-core/motion-gpu).
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
140
166
|
# Quick Start
|
|
141
167
|
|
|
142
168
|
## 1. Create a material and render it
|
|
@@ -144,7 +170,7 @@ npm i @motion-core/motion-gpu
|
|
|
144
170
|
```svelte
|
|
145
171
|
<!-- App.svelte -->
|
|
146
172
|
<script lang="ts">
|
|
147
|
-
import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu';
|
|
173
|
+
import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu/svelte';
|
|
148
174
|
|
|
149
175
|
const material = defineMaterial({
|
|
150
176
|
fragment: `
|
|
@@ -167,7 +193,7 @@ fn frag(uv: vec2f) -> vec4f {
|
|
|
167
193
|
```svelte
|
|
168
194
|
<!-- App.svelte -->
|
|
169
195
|
<script lang="ts">
|
|
170
|
-
import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu';
|
|
196
|
+
import { FragCanvas, defineMaterial } from '@motion-core/motion-gpu/svelte';
|
|
171
197
|
import Runtime from './Runtime.svelte';
|
|
172
198
|
|
|
173
199
|
const material = defineMaterial({
|
|
@@ -191,7 +217,7 @@ fn frag(uv: vec2f) -> vec4f {
|
|
|
191
217
|
```svelte
|
|
192
218
|
<!-- Runtime.svelte -->
|
|
193
219
|
<script lang="ts">
|
|
194
|
-
import { useFrame } from '@motion-core/motion-gpu';
|
|
220
|
+
import { useFrame } from '@motion-core/motion-gpu/svelte';
|
|
195
221
|
|
|
196
222
|
useFrame((state) => {
|
|
197
223
|
state.setUniform('uTime', state.time);
|
package/dist/advanced.d.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Root advanced package entrypoint.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* minimal root API surface.
|
|
4
|
+
* Framework-agnostic advanced core entrypoint.
|
|
6
5
|
*/
|
|
7
|
-
export * from './
|
|
8
|
-
export { applySchedulerPreset, captureSchedulerDebugSnapshot } from './advanced-scheduler';
|
|
9
|
-
export { setMotionGPUUserContext, useMotionGPUUserContext } from './use-motiongpu-user-context';
|
|
10
|
-
export type { ApplySchedulerPresetOptions, SchedulerDebugSnapshot, SchedulerPreset, SchedulerPresetConfig } from './advanced-scheduler';
|
|
11
|
-
export type { MotionGPUUserContext, MotionGPUUserNamespace } from './motiongpu-context';
|
|
12
|
-
export type { FrameProfilingSnapshot, FrameKey, FrameTaskInvalidation, FrameTaskInvalidationToken, FrameRunTimings, FrameScheduleSnapshot, FrameStage, FrameStageCallback, FrameTimingStats, FrameTask } from './frame-context';
|
|
13
|
-
export type { SetMotionGPUUserContextOptions } from './use-motiongpu-user-context';
|
|
14
|
-
export type { RenderPassContext, RenderTarget, UniformLayout, UniformLayoutEntry } from './core/types';
|
|
6
|
+
export * from './core/advanced.js';
|
package/dist/advanced.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Root advanced package entrypoint.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* minimal root API surface.
|
|
4
|
+
* Framework-agnostic advanced core entrypoint.
|
|
6
5
|
*/
|
|
7
|
-
export * from './
|
|
8
|
-
export { applySchedulerPreset, captureSchedulerDebugSnapshot } from './advanced-scheduler';
|
|
9
|
-
export { setMotionGPUUserContext, useMotionGPUUserContext } from './use-motiongpu-user-context';
|
|
6
|
+
export * from './core/advanced.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic advanced MotionGPU core entrypoint.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index.js';
|
|
5
|
+
export { applySchedulerPreset, captureSchedulerDebugSnapshot } from './scheduler-helpers.js';
|
|
6
|
+
export type { ApplySchedulerPresetOptions, MotionGPUScheduler, SchedulerDebugSnapshot, SchedulerPreset, SchedulerPresetConfig } from './scheduler-helpers.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal subscribe contract used by MotionGPU core.
|
|
3
|
+
*/
|
|
4
|
+
export interface Subscribable<T> {
|
|
5
|
+
subscribe: (run: (value: T) => void) => () => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Readable value with synchronous access to the latest value.
|
|
9
|
+
*/
|
|
10
|
+
export interface CurrentReadable<T> extends Subscribable<T> {
|
|
11
|
+
readonly current: T;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Writable extension of {@link CurrentReadable}.
|
|
15
|
+
*/
|
|
16
|
+
export interface CurrentWritable<T> extends CurrentReadable<T> {
|
|
17
|
+
set: (value: T) => void;
|
|
18
|
+
update: (updater: (value: T) => T) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a writable value with immediate subscription semantics.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createCurrentWritable<T>(initialValue: T, onChange?: (value: T) => void): CurrentWritable<T>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a writable value with immediate subscription semantics.
|
|
3
|
+
*/
|
|
4
|
+
export function createCurrentWritable(initialValue, onChange) {
|
|
5
|
+
let current = initialValue;
|
|
6
|
+
const subscribers = new Set();
|
|
7
|
+
const notify = (value) => {
|
|
8
|
+
for (const run of subscribers) {
|
|
9
|
+
run(value);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const set = (value) => {
|
|
13
|
+
if (Object.is(current, value)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
current = value;
|
|
17
|
+
notify(value);
|
|
18
|
+
onChange?.(value);
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
get current() {
|
|
22
|
+
return current;
|
|
23
|
+
},
|
|
24
|
+
subscribe(run) {
|
|
25
|
+
subscribers.add(run);
|
|
26
|
+
run(current);
|
|
27
|
+
return () => {
|
|
28
|
+
subscribers.delete(run);
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
set,
|
|
32
|
+
update(updater) {
|
|
33
|
+
set(updater(current));
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MaterialSourceLocation } from './material-preprocess';
|
|
1
|
+
import type { MaterialSourceLocation } from './material-preprocess.js';
|
|
2
2
|
/**
|
|
3
3
|
* Source metadata for material declaration callsite.
|
|
4
4
|
*/
|
|
@@ -19,6 +19,19 @@ export interface ShaderCompilationDiagnostic {
|
|
|
19
19
|
lineLength?: number;
|
|
20
20
|
sourceLocation: MaterialSourceLocation | null;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Runtime context snapshot captured for shader compilation diagnostics.
|
|
24
|
+
*/
|
|
25
|
+
export interface ShaderCompilationRuntimeContext {
|
|
26
|
+
materialSignature?: string;
|
|
27
|
+
passGraph?: {
|
|
28
|
+
passCount: number;
|
|
29
|
+
enabledPassCount: number;
|
|
30
|
+
inputs: string[];
|
|
31
|
+
outputs: string[];
|
|
32
|
+
};
|
|
33
|
+
activeRenderTargets: string[];
|
|
34
|
+
}
|
|
22
35
|
/**
|
|
23
36
|
* Structured payload attached to WGSL compilation errors.
|
|
24
37
|
*/
|
|
@@ -29,6 +42,7 @@ export interface ShaderCompilationDiagnosticsPayload {
|
|
|
29
42
|
includeSources: Record<string, string>;
|
|
30
43
|
defineBlockSource?: string;
|
|
31
44
|
materialSource: MaterialSourceMetadata | null;
|
|
45
|
+
runtimeContext?: ShaderCompilationRuntimeContext;
|
|
32
46
|
}
|
|
33
47
|
/**
|
|
34
48
|
* Attaches structured diagnostics payload to an Error.
|
|
@@ -56,6 +56,39 @@ function isShaderCompilationDiagnostic(value) {
|
|
|
56
56
|
}
|
|
57
57
|
return true;
|
|
58
58
|
}
|
|
59
|
+
function isStringArray(value) {
|
|
60
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === 'string');
|
|
61
|
+
}
|
|
62
|
+
function isShaderCompilationRuntimeContext(value) {
|
|
63
|
+
if (value === null || typeof value !== 'object') {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const record = value;
|
|
67
|
+
if (record.materialSignature !== undefined && typeof record.materialSignature !== 'string') {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
if (!isStringArray(record.activeRenderTargets)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const passGraph = record.passGraph;
|
|
74
|
+
if (passGraph === undefined) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (passGraph === null || typeof passGraph !== 'object') {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const passGraphRecord = passGraph;
|
|
81
|
+
if (typeof passGraphRecord.passCount !== 'number') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (typeof passGraphRecord.enabledPassCount !== 'number') {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
if (!isStringArray(passGraphRecord.inputs) || !isStringArray(passGraphRecord.outputs)) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
59
92
|
/**
|
|
60
93
|
* Attaches structured diagnostics payload to an Error.
|
|
61
94
|
*/
|
|
@@ -98,6 +131,10 @@ export function getShaderCompilationDiagnostics(error) {
|
|
|
98
131
|
if (record.materialSource !== null && !isMaterialSourceMetadata(record.materialSource)) {
|
|
99
132
|
return null;
|
|
100
133
|
}
|
|
134
|
+
if (record.runtimeContext !== undefined &&
|
|
135
|
+
!isShaderCompilationRuntimeContext(record.runtimeContext)) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
101
138
|
return {
|
|
102
139
|
kind: 'shader-compilation',
|
|
103
140
|
diagnostics: record.diagnostics,
|
|
@@ -106,6 +143,9 @@ export function getShaderCompilationDiagnostics(error) {
|
|
|
106
143
|
...(record.defineBlockSource !== undefined
|
|
107
144
|
? { defineBlockSource: record.defineBlockSource }
|
|
108
145
|
: {}),
|
|
109
|
-
materialSource: (record.materialSource ?? null)
|
|
146
|
+
materialSource: (record.materialSource ?? null),
|
|
147
|
+
...(record.runtimeContext !== undefined
|
|
148
|
+
? { runtimeContext: record.runtimeContext }
|
|
149
|
+
: {})
|
|
110
150
|
};
|
|
111
151
|
}
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
* Runtime phase in which an error occurred.
|
|
3
3
|
*/
|
|
4
4
|
export type MotionGPUErrorPhase = 'initialization' | 'render';
|
|
5
|
+
/**
|
|
6
|
+
* Stable machine-readable error category code.
|
|
7
|
+
*/
|
|
8
|
+
export type MotionGPUErrorCode = 'WEBGPU_UNAVAILABLE' | 'WEBGPU_ADAPTER_UNAVAILABLE' | 'WEBGPU_CONTEXT_UNAVAILABLE' | 'WGSL_COMPILATION_FAILED' | 'WEBGPU_DEVICE_LOST' | 'WEBGPU_UNCAPTURED_ERROR' | 'BIND_GROUP_MISMATCH' | 'TEXTURE_USAGE_INVALID' | 'TEXTURE_REQUEST_FAILED' | 'TEXTURE_DECODE_UNAVAILABLE' | 'TEXTURE_REQUEST_ABORTED' | 'MOTIONGPU_RUNTIME_ERROR';
|
|
9
|
+
/**
|
|
10
|
+
* Severity level for user-facing diagnostics.
|
|
11
|
+
*/
|
|
12
|
+
export type MotionGPUErrorSeverity = 'error' | 'fatal';
|
|
5
13
|
/**
|
|
6
14
|
* One source-code line displayed in diagnostics snippet.
|
|
7
15
|
*/
|
|
@@ -20,10 +28,35 @@ export interface MotionGPUErrorSource {
|
|
|
20
28
|
column?: number;
|
|
21
29
|
snippet: MotionGPUErrorSourceLine[];
|
|
22
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Optional runtime context captured with diagnostics payload.
|
|
33
|
+
*/
|
|
34
|
+
export interface MotionGPUErrorContext {
|
|
35
|
+
materialSignature?: string;
|
|
36
|
+
passGraph?: {
|
|
37
|
+
passCount: number;
|
|
38
|
+
enabledPassCount: number;
|
|
39
|
+
inputs: string[];
|
|
40
|
+
outputs: string[];
|
|
41
|
+
};
|
|
42
|
+
activeRenderTargets: string[];
|
|
43
|
+
}
|
|
23
44
|
/**
|
|
24
45
|
* Structured error payload used by UI diagnostics.
|
|
25
46
|
*/
|
|
26
47
|
export interface MotionGPUErrorReport {
|
|
48
|
+
/**
|
|
49
|
+
* Stable machine-readable category code.
|
|
50
|
+
*/
|
|
51
|
+
code: MotionGPUErrorCode;
|
|
52
|
+
/**
|
|
53
|
+
* Severity level used by diagnostics UIs and telemetry.
|
|
54
|
+
*/
|
|
55
|
+
severity: MotionGPUErrorSeverity;
|
|
56
|
+
/**
|
|
57
|
+
* Whether runtime may recover without full renderer re-creation.
|
|
58
|
+
*/
|
|
59
|
+
recoverable: boolean;
|
|
27
60
|
/**
|
|
28
61
|
* Short category title.
|
|
29
62
|
*/
|
|
@@ -56,6 +89,10 @@ export interface MotionGPUErrorReport {
|
|
|
56
89
|
* Optional source context for shader-related diagnostics.
|
|
57
90
|
*/
|
|
58
91
|
source: MotionGPUErrorSource | null;
|
|
92
|
+
/**
|
|
93
|
+
* Optional runtime context snapshot (material/pass graph/render targets).
|
|
94
|
+
*/
|
|
95
|
+
context: MotionGPUErrorContext | null;
|
|
59
96
|
}
|
|
60
97
|
/**
|
|
61
98
|
* Converts unknown errors to a consistent, display-ready error report.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getShaderCompilationDiagnostics } from './error-diagnostics';
|
|
2
|
-
import { formatShaderSourceLocation } from './shader';
|
|
1
|
+
import { getShaderCompilationDiagnostics } from './error-diagnostics.js';
|
|
2
|
+
import { formatShaderSourceLocation } from './shader.js';
|
|
3
3
|
/**
|
|
4
4
|
* Splits multi-line values into trimmed non-empty lines.
|
|
5
5
|
*/
|
|
@@ -98,53 +98,107 @@ function formatDiagnosticMessage(entry) {
|
|
|
98
98
|
function classifyErrorMessage(message) {
|
|
99
99
|
if (message.includes('WebGPU is not available in this browser')) {
|
|
100
100
|
return {
|
|
101
|
+
code: 'WEBGPU_UNAVAILABLE',
|
|
102
|
+
severity: 'fatal',
|
|
103
|
+
recoverable: false,
|
|
101
104
|
title: 'WebGPU unavailable',
|
|
102
105
|
hint: 'Use a browser with WebGPU enabled (latest Chrome/Edge/Safari TP) and secure context.'
|
|
103
106
|
};
|
|
104
107
|
}
|
|
105
108
|
if (message.includes('Unable to acquire WebGPU adapter')) {
|
|
106
109
|
return {
|
|
110
|
+
code: 'WEBGPU_ADAPTER_UNAVAILABLE',
|
|
111
|
+
severity: 'fatal',
|
|
112
|
+
recoverable: false,
|
|
107
113
|
title: 'WebGPU adapter unavailable',
|
|
108
114
|
hint: 'GPU adapter request failed. Check browser permissions, flags and device support.'
|
|
109
115
|
};
|
|
110
116
|
}
|
|
111
117
|
if (message.includes('Canvas does not support webgpu context')) {
|
|
112
118
|
return {
|
|
119
|
+
code: 'WEBGPU_CONTEXT_UNAVAILABLE',
|
|
120
|
+
severity: 'error',
|
|
121
|
+
recoverable: true,
|
|
113
122
|
title: 'Canvas cannot create WebGPU context',
|
|
114
123
|
hint: 'Make sure this canvas is attached to DOM and not using an unsupported context option.'
|
|
115
124
|
};
|
|
116
125
|
}
|
|
117
126
|
if (message.includes('WGSL compilation failed')) {
|
|
118
127
|
return {
|
|
128
|
+
code: 'WGSL_COMPILATION_FAILED',
|
|
129
|
+
severity: 'error',
|
|
130
|
+
recoverable: true,
|
|
119
131
|
title: 'WGSL compilation failed',
|
|
120
132
|
hint: 'Check WGSL line numbers below and verify struct/binding/function signatures.'
|
|
121
133
|
};
|
|
122
134
|
}
|
|
123
135
|
if (message.includes('WebGPU device lost') || message.includes('Device Lost')) {
|
|
124
136
|
return {
|
|
137
|
+
code: 'WEBGPU_DEVICE_LOST',
|
|
138
|
+
severity: 'fatal',
|
|
139
|
+
recoverable: false,
|
|
125
140
|
title: 'WebGPU device lost',
|
|
126
141
|
hint: 'GPU device/context was lost. Recreate the renderer and check OS/GPU stability.'
|
|
127
142
|
};
|
|
128
143
|
}
|
|
129
144
|
if (message.includes('WebGPU uncaptured error')) {
|
|
130
145
|
return {
|
|
146
|
+
code: 'WEBGPU_UNCAPTURED_ERROR',
|
|
147
|
+
severity: 'error',
|
|
148
|
+
recoverable: true,
|
|
131
149
|
title: 'WebGPU uncaptured error',
|
|
132
150
|
hint: 'A GPU command failed asynchronously. Review details and validate resource/state usage.'
|
|
133
151
|
};
|
|
134
152
|
}
|
|
135
153
|
if (message.includes('CreateBindGroup') || message.includes('bind group layout')) {
|
|
136
154
|
return {
|
|
155
|
+
code: 'BIND_GROUP_MISMATCH',
|
|
156
|
+
severity: 'error',
|
|
157
|
+
recoverable: true,
|
|
137
158
|
title: 'Bind group mismatch',
|
|
138
159
|
hint: 'Bindings in shader and runtime resources are out of sync. Verify uniforms/textures layout.'
|
|
139
160
|
};
|
|
140
161
|
}
|
|
141
162
|
if (message.includes('Destination texture needs to have CopyDst')) {
|
|
142
163
|
return {
|
|
164
|
+
code: 'TEXTURE_USAGE_INVALID',
|
|
165
|
+
severity: 'error',
|
|
166
|
+
recoverable: true,
|
|
143
167
|
title: 'Invalid texture usage flags',
|
|
144
168
|
hint: 'Texture used as upload destination must include CopyDst (and often RenderAttachment).'
|
|
145
169
|
};
|
|
146
170
|
}
|
|
171
|
+
if (message.includes('Texture request failed')) {
|
|
172
|
+
return {
|
|
173
|
+
code: 'TEXTURE_REQUEST_FAILED',
|
|
174
|
+
severity: 'error',
|
|
175
|
+
recoverable: true,
|
|
176
|
+
title: 'Texture request failed',
|
|
177
|
+
hint: 'Verify texture URL, CORS policy and response status before retrying.'
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (message.includes('createImageBitmap is not available in this runtime')) {
|
|
181
|
+
return {
|
|
182
|
+
code: 'TEXTURE_DECODE_UNAVAILABLE',
|
|
183
|
+
severity: 'fatal',
|
|
184
|
+
recoverable: false,
|
|
185
|
+
title: 'Texture decode unavailable',
|
|
186
|
+
hint: 'Runtime lacks createImageBitmap support. Use a browser/runtime with image bitmap decoding.'
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (message.toLowerCase().includes('texture request was aborted')) {
|
|
190
|
+
return {
|
|
191
|
+
code: 'TEXTURE_REQUEST_ABORTED',
|
|
192
|
+
severity: 'error',
|
|
193
|
+
recoverable: true,
|
|
194
|
+
title: 'Texture request aborted',
|
|
195
|
+
hint: 'Texture load was cancelled. Retry the request when source inputs stabilize.'
|
|
196
|
+
};
|
|
197
|
+
}
|
|
147
198
|
return {
|
|
199
|
+
code: 'MOTIONGPU_RUNTIME_ERROR',
|
|
200
|
+
severity: 'error',
|
|
201
|
+
recoverable: true,
|
|
148
202
|
title: 'MotionGPU render error',
|
|
149
203
|
hint: 'Review technical details below. If issue persists, isolate shader/uniform/texture changes.'
|
|
150
204
|
};
|
|
@@ -167,6 +221,7 @@ export function toMotionGPUErrorReport(error, phase) {
|
|
|
167
221
|
const defaultMessage = rawLines[0] ?? rawMessage;
|
|
168
222
|
const defaultDetails = rawLines.slice(1);
|
|
169
223
|
const source = buildSourceFromDiagnostics(error);
|
|
224
|
+
const context = shaderDiagnostics?.runtimeContext ?? null;
|
|
170
225
|
const message = shaderDiagnostics && shaderDiagnostics.diagnostics[0]
|
|
171
226
|
? formatDiagnosticMessage(shaderDiagnostics.diagnostics[0])
|
|
172
227
|
: defaultMessage;
|
|
@@ -178,6 +233,9 @@ export function toMotionGPUErrorReport(error, phase) {
|
|
|
178
233
|
: [];
|
|
179
234
|
const classification = classifyErrorMessage(rawMessage);
|
|
180
235
|
return {
|
|
236
|
+
code: classification.code,
|
|
237
|
+
severity: classification.severity,
|
|
238
|
+
recoverable: classification.recoverable,
|
|
181
239
|
title: classification.title,
|
|
182
240
|
message,
|
|
183
241
|
hint: classification.hint,
|
|
@@ -185,6 +243,7 @@ export function toMotionGPUErrorReport(error, phase) {
|
|
|
185
243
|
stack,
|
|
186
244
|
rawMessage,
|
|
187
245
|
phase,
|
|
188
|
-
source
|
|
246
|
+
source,
|
|
247
|
+
context
|
|
189
248
|
};
|
|
190
249
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { FrameInvalidationToken, FrameState, RenderMode } from './
|
|
1
|
+
import { type Subscribable } from './current-value.js';
|
|
2
|
+
import type { FrameInvalidationToken, FrameState, RenderMode } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Per-frame callback executed by the frame scheduler.
|
|
5
5
|
*/
|
|
@@ -97,7 +97,7 @@ export interface UseFrameResult {
|
|
|
97
97
|
/**
|
|
98
98
|
* Readable flag representing effective running state.
|
|
99
99
|
*/
|
|
100
|
-
started:
|
|
100
|
+
started: Subscribable<boolean>;
|
|
101
101
|
}
|
|
102
102
|
/**
|
|
103
103
|
* Snapshot of the resolved stage/task execution order.
|
|
@@ -270,18 +270,4 @@ export declare function createFrameRegistry(options?: {
|
|
|
270
270
|
profilingWindow?: number;
|
|
271
271
|
diagnosticsEnabled?: boolean;
|
|
272
272
|
}): FrameRegistry;
|
|
273
|
-
/**
|
|
274
|
-
* Provides a frame registry through Svelte context.
|
|
275
|
-
*
|
|
276
|
-
* @param registry - Registry to provide.
|
|
277
|
-
*/
|
|
278
|
-
export declare function provideFrameRegistry(registry: FrameRegistry): void;
|
|
279
|
-
/**
|
|
280
|
-
* Registers a frame callback using an auto-generated task key.
|
|
281
|
-
*/
|
|
282
|
-
export declare function useFrame(callback: FrameCallback, options?: UseFrameOptions): UseFrameResult;
|
|
283
|
-
/**
|
|
284
|
-
* Registers a frame callback with an explicit task key.
|
|
285
|
-
*/
|
|
286
|
-
export declare function useFrame(key: FrameKey, callback: FrameCallback, options?: UseFrameOptions): UseFrameResult;
|
|
287
273
|
export {};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { writable } from 'svelte/store';
|
|
3
|
-
/**
|
|
4
|
-
* Svelte context key for the active frame registry.
|
|
5
|
-
*/
|
|
6
|
-
const FRAME_CONTEXT_KEY = Symbol('motiongpu.frame-context');
|
|
1
|
+
import { createCurrentWritable } from './current-value.js';
|
|
7
2
|
/**
|
|
8
3
|
* Default stage key used when task stage is not explicitly specified.
|
|
9
4
|
*/
|
|
@@ -492,7 +487,7 @@ export function createFrameRegistry(options) {
|
|
|
492
487
|
? toStageKey(taskOptions.stage)
|
|
493
488
|
: (inferredStage?.stage ?? MAIN_STAGE_KEY);
|
|
494
489
|
const stage = ensureStage(stageKey);
|
|
495
|
-
const startedWritable =
|
|
490
|
+
const startedWritable = createCurrentWritable(taskOptions.autoStart ?? true);
|
|
496
491
|
const internalTask = {
|
|
497
492
|
task: { key, stage: stage.key },
|
|
498
493
|
callback,
|
|
@@ -699,33 +694,3 @@ export function createFrameRegistry(options) {
|
|
|
699
694
|
}
|
|
700
695
|
};
|
|
701
696
|
}
|
|
702
|
-
/**
|
|
703
|
-
* Provides a frame registry through Svelte context.
|
|
704
|
-
*
|
|
705
|
-
* @param registry - Registry to provide.
|
|
706
|
-
*/
|
|
707
|
-
export function provideFrameRegistry(registry) {
|
|
708
|
-
setContext(FRAME_CONTEXT_KEY, registry);
|
|
709
|
-
}
|
|
710
|
-
/**
|
|
711
|
-
* Registers a callback in the active frame registry and auto-unsubscribes on destroy.
|
|
712
|
-
*
|
|
713
|
-
* @returns Frame task handle for start/stop control.
|
|
714
|
-
* @throws {Error} When used outside `<FragCanvas>`.
|
|
715
|
-
*/
|
|
716
|
-
export function useFrame(keyOrCallback, callbackOrOptions, maybeOptions) {
|
|
717
|
-
const registry = getContext(FRAME_CONTEXT_KEY);
|
|
718
|
-
if (!registry) {
|
|
719
|
-
throw new Error('useFrame must be used inside <FragCanvas>');
|
|
720
|
-
}
|
|
721
|
-
const registration = typeof keyOrCallback === 'function'
|
|
722
|
-
? registry.register(keyOrCallback, callbackOrOptions)
|
|
723
|
-
: registry.register(keyOrCallback, callbackOrOptions, maybeOptions);
|
|
724
|
-
onDestroy(registration.unsubscribe);
|
|
725
|
-
return {
|
|
726
|
-
task: registration.task,
|
|
727
|
-
start: registration.start,
|
|
728
|
-
stop: registration.stop,
|
|
729
|
-
started: registration.started
|
|
730
|
-
};
|
|
731
|
-
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic MotionGPU core entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* This surface is intended for building framework adapters (Svelte/React/Vue).
|
|
5
|
+
*/
|
|
6
|
+
export { defineMaterial, resolveMaterial } from './material.js';
|
|
7
|
+
export { toMotionGPUErrorReport } from './error-report.js';
|
|
8
|
+
export { createCurrentWritable } from './current-value.js';
|
|
9
|
+
export { createFrameRegistry } from './frame-registry.js';
|
|
10
|
+
export { createMotionGPURuntimeLoop } from './runtime-loop.js';
|
|
11
|
+
export { loadTexturesFromUrls } from './texture-loader.js';
|
|
12
|
+
export { BlitPass, CopyPass, ShaderPass } from '../passes/index.js';
|
|
13
|
+
export type { CurrentReadable, CurrentWritable, Subscribable } from './current-value.js';
|
|
14
|
+
export type { MotionGPUErrorCode, MotionGPUErrorContext, MotionGPUErrorPhase, MotionGPUErrorReport, MotionGPUErrorSeverity, MotionGPUErrorSource, MotionGPUErrorSourceLine } from './error-report.js';
|
|
15
|
+
export type { FrameCallback, FrameKey, FrameProfilingSnapshot, FrameRegistry, FrameRunTimings, FrameScheduleSnapshot, FrameStage, FrameStageCallback, FrameTask, FrameTaskInvalidation, FrameTaskInvalidationToken, FrameTimingStats, UseFrameOptions, UseFrameResult } from './frame-registry.js';
|
|
16
|
+
export type { FragMaterial, FragMaterialInput, MaterialDefineValue, MaterialDefines, MaterialIncludes, ResolvedMaterial, TypedMaterialDefineValue } from './material.js';
|
|
17
|
+
export type { MotionGPURuntimeLoop, MotionGPURuntimeLoopOptions } from './runtime-loop.js';
|
|
18
|
+
export type { LoadedTexture, TextureDecodeOptions, TextureLoadOptions } from './texture-loader.js';
|
|
19
|
+
export type { FrameInvalidationToken, FrameState, OutputColorSpace, RenderPass, RenderPassContext, RenderPassFlags, RenderPassInputSlot, RenderPassOutputSlot, RenderMode, RenderTarget, RenderTargetDefinition, RenderTargetDefinitionMap, TextureData, TextureDefinition, TextureDefinitionMap, TextureMap, TextureSource, TextureUpdateMode, TextureValue, TypedUniform, UniformLayout, UniformLayoutEntry, UniformMap, UniformMat4Value, UniformType, UniformValue } from './types.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-agnostic MotionGPU core entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* This surface is intended for building framework adapters (Svelte/React/Vue).
|
|
5
|
+
*/
|
|
6
|
+
export { defineMaterial, resolveMaterial } from './material.js';
|
|
7
|
+
export { toMotionGPUErrorReport } from './error-report.js';
|
|
8
|
+
export { createCurrentWritable } from './current-value.js';
|
|
9
|
+
export { createFrameRegistry } from './frame-registry.js';
|
|
10
|
+
export { createMotionGPURuntimeLoop } from './runtime-loop.js';
|
|
11
|
+
export { loadTexturesFromUrls } from './texture-loader.js';
|
|
12
|
+
export { BlitPass, CopyPass, ShaderPass } from '../passes/index.js';
|
package/dist/core/material.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { MaterialSourceMetadata } from './error-diagnostics';
|
|
2
|
-
import { resolveUniformLayout } from './uniforms';
|
|
3
|
-
import { type MaterialLineMap } from './material-preprocess';
|
|
4
|
-
import type { TextureDefinitionMap, UniformMap } from './types';
|
|
1
|
+
import type { MaterialSourceMetadata } from './error-diagnostics.js';
|
|
2
|
+
import { resolveUniformLayout } from './uniforms.js';
|
|
3
|
+
import { type MaterialLineMap } from './material-preprocess.js';
|
|
4
|
+
import type { TextureDefinitionMap, UniformMap } from './types.js';
|
|
5
5
|
/**
|
|
6
6
|
* Typed compile-time define declaration.
|
|
7
7
|
*/
|