@motion-core/motion-gpu 0.4.2 → 0.6.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.js +3 -1
- package/dist/core/advanced.js +3 -1
- package/dist/core/compute-bindgroup-cache.d.ts +13 -0
- package/dist/core/compute-bindgroup-cache.d.ts.map +1 -0
- package/dist/core/compute-bindgroup-cache.js +45 -0
- package/dist/core/compute-bindgroup-cache.js.map +1 -0
- package/dist/core/compute-shader.d.ts +135 -0
- package/dist/core/compute-shader.d.ts.map +1 -0
- package/dist/core/compute-shader.js +238 -0
- package/dist/core/compute-shader.js.map +1 -0
- package/dist/core/error-diagnostics.d.ts +8 -1
- package/dist/core/error-diagnostics.d.ts.map +1 -1
- package/dist/core/error-diagnostics.js +7 -3
- package/dist/core/error-diagnostics.js.map +1 -1
- package/dist/core/error-report.d.ts +1 -1
- package/dist/core/error-report.d.ts.map +1 -1
- package/dist/core/error-report.js +82 -1
- package/dist/core/error-report.js.map +1 -1
- package/dist/core/frame-registry.d.ts.map +1 -1
- package/dist/core/frame-registry.js +1 -1
- package/dist/core/frame-registry.js.map +1 -1
- package/dist/core/index.d.ts +5 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -1
- package/dist/core/material-preprocess.d.ts.map +1 -1
- package/dist/core/material-preprocess.js +5 -3
- package/dist/core/material-preprocess.js.map +1 -1
- package/dist/core/material.d.ts +22 -6
- package/dist/core/material.d.ts.map +1 -1
- package/dist/core/material.js +32 -4
- package/dist/core/material.js.map +1 -1
- package/dist/core/render-graph.d.ts +7 -3
- package/dist/core/render-graph.d.ts.map +1 -1
- package/dist/core/render-graph.js +22 -6
- package/dist/core/render-graph.js.map +1 -1
- package/dist/core/renderer.d.ts.map +1 -1
- package/dist/core/renderer.js +489 -29
- package/dist/core/renderer.js.map +1 -1
- package/dist/core/runtime-loop.d.ts +2 -2
- package/dist/core/runtime-loop.d.ts.map +1 -1
- package/dist/core/runtime-loop.js +74 -14
- package/dist/core/runtime-loop.js.map +1 -1
- package/dist/core/shader.d.ts +16 -3
- package/dist/core/shader.d.ts.map +1 -1
- package/dist/core/shader.js +22 -2
- package/dist/core/shader.js.map +1 -1
- 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.map +1 -1
- package/dist/core/texture-loader.js +4 -0
- package/dist/core/texture-loader.js.map +1 -1
- package/dist/core/textures.d.ts +16 -0
- package/dist/core/textures.d.ts.map +1 -1
- package/dist/core/textures.js +8 -2
- package/dist/core/textures.js.map +1 -1
- package/dist/core/types.d.ts +146 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.js +3 -1
- 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/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.map +1 -1
- package/dist/passes/ShaderPass.js +2 -1
- package/dist/passes/ShaderPass.js.map +1 -1
- package/dist/passes/index.d.ts +2 -0
- package/dist/passes/index.d.ts.map +1 -1
- package/dist/passes/index.js +3 -1
- package/dist/react/FragCanvas.d.ts +2 -2
- package/dist/react/FragCanvas.d.ts.map +1 -1
- package/dist/react/FragCanvas.js.map +1 -1
- package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -1
- package/dist/react/MotionGPUErrorOverlay.js +123 -20
- package/dist/react/MotionGPUErrorOverlay.js.map +1 -1
- package/dist/react/advanced.js +3 -1
- package/dist/react/index.d.ts +5 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -1
- package/dist/svelte/FragCanvas.svelte +2 -2
- package/dist/svelte/FragCanvas.svelte.d.ts +2 -2
- package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -1
- package/dist/svelte/MotionGPUErrorOverlay.svelte +137 -7
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -1
- package/dist/svelte/advanced.js +3 -1
- package/dist/svelte/index.d.ts +5 -2
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +3 -1
- package/package.json +1 -1
- package/src/lib/core/compute-bindgroup-cache.ts +73 -0
- package/src/lib/core/compute-shader.ts +412 -0
- package/src/lib/core/error-diagnostics.ts +29 -4
- package/src/lib/core/error-report.ts +155 -1
- package/src/lib/core/frame-registry.ts +2 -1
- package/src/lib/core/index.ts +18 -1
- package/src/lib/core/material-preprocess.ts +17 -6
- package/src/lib/core/material.ts +103 -21
- package/src/lib/core/render-graph.ts +39 -9
- package/src/lib/core/renderer.ts +768 -48
- package/src/lib/core/runtime-loop.ts +116 -16
- package/src/lib/core/shader.ts +58 -4
- package/src/lib/core/storage-buffers.ts +142 -0
- package/src/lib/core/texture-loader.ts +6 -0
- package/src/lib/core/textures.ts +29 -2
- package/src/lib/core/types.ts +165 -4
- package/src/lib/passes/ComputePass.ts +136 -0
- package/src/lib/passes/PingPongComputePass.ts +180 -0
- package/src/lib/passes/ShaderPass.ts +2 -1
- package/src/lib/passes/index.ts +6 -0
- package/src/lib/react/FragCanvas.tsx +3 -3
- package/src/lib/react/MotionGPUErrorOverlay.tsx +137 -5
- package/src/lib/react/index.ts +18 -1
- package/src/lib/svelte/FragCanvas.svelte +2 -2
- package/src/lib/svelte/MotionGPUErrorOverlay.svelte +137 -7
- package/src/lib/svelte/index.ts +18 -1
|
@@ -75,6 +75,19 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
|
|
|
75
75
|
border-bottom: 1px solid var(--motiongpu-color-border);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
.motiongpu-error-header-top {
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: flex-start;
|
|
81
|
+
gap: 0.75rem;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.motiongpu-error-badges {
|
|
85
|
+
display: inline-flex;
|
|
86
|
+
align-items: center;
|
|
87
|
+
gap: 0.4rem;
|
|
88
|
+
flex-wrap: wrap;
|
|
89
|
+
}
|
|
90
|
+
|
|
78
91
|
.motiongpu-error-badge-wrap {
|
|
79
92
|
display: inline-flex;
|
|
80
93
|
align-items: center;
|
|
@@ -86,7 +99,7 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
|
|
|
86
99
|
background: var(--motiongpu-color-background-muted);
|
|
87
100
|
}
|
|
88
101
|
|
|
89
|
-
.motiongpu-error-
|
|
102
|
+
.motiongpu-error-badge {
|
|
90
103
|
display: inline-flex;
|
|
91
104
|
align-items: center;
|
|
92
105
|
margin: 0;
|
|
@@ -106,6 +119,20 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
|
|
|
106
119
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);
|
|
107
120
|
}
|
|
108
121
|
|
|
122
|
+
.motiongpu-error-recoverable {
|
|
123
|
+
margin: 0;
|
|
124
|
+
font-size: 0.67rem;
|
|
125
|
+
line-height: 1.2;
|
|
126
|
+
letter-spacing: 0.06em;
|
|
127
|
+
text-transform: uppercase;
|
|
128
|
+
color: var(--motiongpu-color-foreground-muted);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.motiongpu-error-recoverable span {
|
|
132
|
+
font-family: var(--motiongpu-font-mono);
|
|
133
|
+
color: var(--motiongpu-color-foreground);
|
|
134
|
+
}
|
|
135
|
+
|
|
109
136
|
.motiongpu-error-title {
|
|
110
137
|
margin: 0;
|
|
111
138
|
font-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);
|
|
@@ -285,6 +312,11 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
|
|
|
285
312
|
.motiongpu-error-title {
|
|
286
313
|
font-size: 1.02rem;
|
|
287
314
|
}
|
|
315
|
+
|
|
316
|
+
.motiongpu-error-header-top {
|
|
317
|
+
flex-direction: column;
|
|
318
|
+
align-items: flex-start;
|
|
319
|
+
}
|
|
288
320
|
}
|
|
289
321
|
|
|
290
322
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -302,7 +334,87 @@ function normalizeErrorText(value: string): string {
|
|
|
302
334
|
}
|
|
303
335
|
|
|
304
336
|
function shouldShowErrorMessage(value: MotionGPUErrorReport): boolean {
|
|
305
|
-
return
|
|
337
|
+
return resolveDisplayMessage(value).length > 0;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function resolveDisplayMessage(value: MotionGPUErrorReport): string {
|
|
341
|
+
const rawMessage = value.message.trim();
|
|
342
|
+
if (rawMessage.length === 0) {
|
|
343
|
+
return '';
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const normalizedMessage = normalizeErrorText(rawMessage);
|
|
347
|
+
const normalizedTitle = normalizeErrorText(value.title);
|
|
348
|
+
if (normalizedMessage === normalizedTitle) {
|
|
349
|
+
return '';
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const escapedTitle = value.title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
353
|
+
const prefixPattern = new RegExp(`^${escapedTitle}\\s*[:\\-|]\\s*`, 'i');
|
|
354
|
+
const stripped = rawMessage.replace(prefixPattern, '').trim();
|
|
355
|
+
return stripped.length > 0 ? stripped : rawMessage;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function formatRuntimeContext(context: MotionGPUErrorReport['context']): string {
|
|
359
|
+
if (!context) {
|
|
360
|
+
return '';
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const indentBlock = (value: string, spaces = 2): string => {
|
|
364
|
+
const prefix = ' '.repeat(spaces);
|
|
365
|
+
return value
|
|
366
|
+
.split('\n')
|
|
367
|
+
.map((line) => `${prefix}${line}`)
|
|
368
|
+
.join('\n');
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const formatMaterialSignature = (value: string): string => {
|
|
372
|
+
const trimmed = value.trim();
|
|
373
|
+
if (trimmed.length === 0) {
|
|
374
|
+
return '<empty>';
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
return JSON.stringify(JSON.parse(trimmed), null, 2);
|
|
378
|
+
} catch {
|
|
379
|
+
return trimmed;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const lines: string[] = [];
|
|
384
|
+
if (context.materialSignature) {
|
|
385
|
+
lines.push('materialSignature:');
|
|
386
|
+
lines.push(indentBlock(formatMaterialSignature(context.materialSignature)));
|
|
387
|
+
}
|
|
388
|
+
if (context.passGraph) {
|
|
389
|
+
lines.push('passGraph:');
|
|
390
|
+
lines.push(` passCount: ${context.passGraph.passCount}`);
|
|
391
|
+
lines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);
|
|
392
|
+
lines.push(' inputs:');
|
|
393
|
+
if (context.passGraph.inputs.length === 0) {
|
|
394
|
+
lines.push(' - <none>');
|
|
395
|
+
} else {
|
|
396
|
+
for (const input of context.passGraph.inputs) {
|
|
397
|
+
lines.push(` - ${input}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
lines.push(' outputs:');
|
|
401
|
+
if (context.passGraph.outputs.length === 0) {
|
|
402
|
+
lines.push(' - <none>');
|
|
403
|
+
} else {
|
|
404
|
+
for (const output of context.passGraph.outputs) {
|
|
405
|
+
lines.push(` - ${output}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
lines.push('activeRenderTargets:');
|
|
410
|
+
if (context.activeRenderTargets.length === 0) {
|
|
411
|
+
lines.push(' - <none>');
|
|
412
|
+
} else {
|
|
413
|
+
for (const target of context.activeRenderTargets) {
|
|
414
|
+
lines.push(` - ${target}`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return lines.join('\n');
|
|
306
418
|
}
|
|
307
419
|
|
|
308
420
|
export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
|
|
@@ -320,14 +432,28 @@ export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
|
|
|
320
432
|
data-testid="motiongpu-error"
|
|
321
433
|
>
|
|
322
434
|
<header className="motiongpu-error-header">
|
|
323
|
-
<div className="motiongpu-error-
|
|
324
|
-
<
|
|
435
|
+
<div className="motiongpu-error-header-top">
|
|
436
|
+
<div className="motiongpu-error-badges">
|
|
437
|
+
<div className="motiongpu-error-badge-wrap">
|
|
438
|
+
<p className="motiongpu-error-badge motiongpu-error-badge-phase">
|
|
439
|
+
{report.phase}
|
|
440
|
+
</p>
|
|
441
|
+
</div>
|
|
442
|
+
<div className="motiongpu-error-badge-wrap">
|
|
443
|
+
<p className="motiongpu-error-badge motiongpu-error-badge-severity">
|
|
444
|
+
{report.severity}
|
|
445
|
+
</p>
|
|
446
|
+
</div>
|
|
447
|
+
</div>
|
|
325
448
|
</div>
|
|
326
449
|
<h2 className="motiongpu-error-title">{report.title}</h2>
|
|
450
|
+
<p className="motiongpu-error-recoverable">
|
|
451
|
+
Recoverable: <span>{report.recoverable ? 'yes' : 'no'}</span>
|
|
452
|
+
</p>
|
|
327
453
|
</header>
|
|
328
454
|
<div className="motiongpu-error-body">
|
|
329
455
|
{shouldShowErrorMessage(report) ? (
|
|
330
|
-
<p className="motiongpu-error-message">{report
|
|
456
|
+
<p className="motiongpu-error-message">{resolveDisplayMessage(report)}</p>
|
|
331
457
|
) : null}
|
|
332
458
|
<p className="motiongpu-error-hint">{report.hint}</p>
|
|
333
459
|
</div>
|
|
@@ -384,6 +510,12 @@ export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
|
|
|
384
510
|
<pre>{report.stack.join('\n')}</pre>
|
|
385
511
|
</details>
|
|
386
512
|
) : null}
|
|
513
|
+
{report.context ? (
|
|
514
|
+
<details className="motiongpu-error-details">
|
|
515
|
+
<summary>Runtime context</summary>
|
|
516
|
+
<pre>{formatRuntimeContext(report.context)}</pre>
|
|
517
|
+
</details>
|
|
518
|
+
) : null}
|
|
387
519
|
</div>
|
|
388
520
|
</section>
|
|
389
521
|
</div>
|
package/src/lib/react/index.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { FragCanvas } from './FragCanvas.js';
|
|
5
5
|
export { defineMaterial } from '../core/material.js';
|
|
6
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
BlitPass,
|
|
8
|
+
CopyPass,
|
|
9
|
+
ShaderPass,
|
|
10
|
+
ComputePass,
|
|
11
|
+
PingPongComputePass
|
|
12
|
+
} from '../passes/index.js';
|
|
7
13
|
export { useMotionGPU } from './motiongpu-context.js';
|
|
8
14
|
export { useFrame } from './frame-context.js';
|
|
9
15
|
export { useTexture } from './use-texture.js';
|
|
@@ -11,6 +17,8 @@ export type {
|
|
|
11
17
|
FrameInvalidationToken,
|
|
12
18
|
FrameState,
|
|
13
19
|
OutputColorSpace,
|
|
20
|
+
AnyPass,
|
|
21
|
+
ComputePassLike,
|
|
14
22
|
RenderPass,
|
|
15
23
|
RenderPassContext,
|
|
16
24
|
RenderPassFlags,
|
|
@@ -49,3 +57,12 @@ export type {
|
|
|
49
57
|
export type { MotionGPUContext } from './motiongpu-context.js';
|
|
50
58
|
export type { UseFrameOptions, UseFrameResult } from './frame-context.js';
|
|
51
59
|
export type { TextureUrlInput, UseTextureResult } from './use-texture.js';
|
|
60
|
+
export type {
|
|
61
|
+
StorageBufferAccess,
|
|
62
|
+
StorageBufferDefinition,
|
|
63
|
+
StorageBufferDefinitionMap,
|
|
64
|
+
StorageBufferType,
|
|
65
|
+
ComputePassContext
|
|
66
|
+
} from '../core/types.js';
|
|
67
|
+
export type { ComputePassOptions, ComputeDispatchContext } from '../passes/ComputePass.js';
|
|
68
|
+
export type { PingPongComputePassOptions } from '../passes/PingPongComputePass.js';
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import MotionGPUErrorOverlay from './MotionGPUErrorOverlay.svelte';
|
|
8
8
|
import { createMotionGPURuntimeLoop } from '../core/runtime-loop';
|
|
9
9
|
import type {
|
|
10
|
+
AnyPass,
|
|
10
11
|
FrameInvalidationToken,
|
|
11
12
|
OutputColorSpace,
|
|
12
|
-
RenderPass,
|
|
13
13
|
RenderMode,
|
|
14
14
|
RenderTargetDefinitionMap
|
|
15
15
|
} from '../core/types';
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
interface Props {
|
|
20
20
|
material: FragMaterial;
|
|
21
21
|
renderTargets?: RenderTargetDefinitionMap;
|
|
22
|
-
passes?:
|
|
22
|
+
passes?: AnyPass[];
|
|
23
23
|
clearColor?: [number, number, number, number];
|
|
24
24
|
outputColorSpace?: OutputColorSpace;
|
|
25
25
|
renderMode?: RenderMode;
|
|
@@ -16,7 +16,87 @@
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
const shouldShowErrorMessage = (value: MotionGPUErrorReport): boolean => {
|
|
19
|
-
return
|
|
19
|
+
return resolveDisplayMessage(value).length > 0;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const resolveDisplayMessage = (value: MotionGPUErrorReport): string => {
|
|
23
|
+
const rawMessage = value.message.trim();
|
|
24
|
+
if (rawMessage.length === 0) {
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const normalizedMessage = normalizeErrorText(rawMessage);
|
|
29
|
+
const normalizedTitle = normalizeErrorText(value.title);
|
|
30
|
+
if (normalizedMessage === normalizedTitle) {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const escapedTitle = value.title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
35
|
+
const prefixPattern = new RegExp(`^${escapedTitle}\\s*[:\\-|]\\s*`, 'i');
|
|
36
|
+
const stripped = rawMessage.replace(prefixPattern, '').trim();
|
|
37
|
+
return stripped.length > 0 ? stripped : rawMessage;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const formatRuntimeContext = (context: MotionGPUErrorReport['context']): string => {
|
|
41
|
+
if (!context) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const indentBlock = (value: string, spaces = 2): string => {
|
|
46
|
+
const prefix = ' '.repeat(spaces);
|
|
47
|
+
return value
|
|
48
|
+
.split('\n')
|
|
49
|
+
.map((line) => `${prefix}${line}`)
|
|
50
|
+
.join('\n');
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const formatMaterialSignature = (value: string): string => {
|
|
54
|
+
const trimmed = value.trim();
|
|
55
|
+
if (trimmed.length === 0) {
|
|
56
|
+
return '<empty>';
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return JSON.stringify(JSON.parse(trimmed), null, 2);
|
|
60
|
+
} catch {
|
|
61
|
+
return trimmed;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const lines: string[] = [];
|
|
66
|
+
if (context.materialSignature) {
|
|
67
|
+
lines.push('materialSignature:');
|
|
68
|
+
lines.push(indentBlock(formatMaterialSignature(context.materialSignature)));
|
|
69
|
+
}
|
|
70
|
+
if (context.passGraph) {
|
|
71
|
+
lines.push('passGraph:');
|
|
72
|
+
lines.push(` passCount: ${context.passGraph.passCount}`);
|
|
73
|
+
lines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);
|
|
74
|
+
lines.push(' inputs:');
|
|
75
|
+
if (context.passGraph.inputs.length === 0) {
|
|
76
|
+
lines.push(' - <none>');
|
|
77
|
+
} else {
|
|
78
|
+
for (const input of context.passGraph.inputs) {
|
|
79
|
+
lines.push(` - ${input}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
lines.push(' outputs:');
|
|
83
|
+
if (context.passGraph.outputs.length === 0) {
|
|
84
|
+
lines.push(' - <none>');
|
|
85
|
+
} else {
|
|
86
|
+
for (const output of context.passGraph.outputs) {
|
|
87
|
+
lines.push(` - ${output}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
lines.push('activeRenderTargets:');
|
|
92
|
+
if (context.activeRenderTargets.length === 0) {
|
|
93
|
+
lines.push(' - <none>');
|
|
94
|
+
} else {
|
|
95
|
+
for (const target of context.activeRenderTargets) {
|
|
96
|
+
lines.push(` - ${target}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return lines.join('\n');
|
|
20
100
|
};
|
|
21
101
|
</script>
|
|
22
102
|
|
|
@@ -30,16 +110,28 @@
|
|
|
30
110
|
data-testid="motiongpu-error"
|
|
31
111
|
>
|
|
32
112
|
<header class="motiongpu-error-header">
|
|
33
|
-
<div class="motiongpu-error-
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
113
|
+
<div class="motiongpu-error-header-top">
|
|
114
|
+
<div class="motiongpu-error-badges">
|
|
115
|
+
<div class="motiongpu-error-badge-wrap">
|
|
116
|
+
<p class="motiongpu-error-badge motiongpu-error-badge-phase">
|
|
117
|
+
{report.phase}
|
|
118
|
+
</p>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="motiongpu-error-badge-wrap">
|
|
121
|
+
<p class="motiongpu-error-badge motiongpu-error-badge-severity">
|
|
122
|
+
{report.severity}
|
|
123
|
+
</p>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
37
126
|
</div>
|
|
38
127
|
<h2 class="motiongpu-error-title">{report.title}</h2>
|
|
128
|
+
<p class="motiongpu-error-recoverable">
|
|
129
|
+
Recoverable: <span>{report.recoverable ? 'yes' : 'no'}</span>
|
|
130
|
+
</p>
|
|
39
131
|
</header>
|
|
40
132
|
<div class="motiongpu-error-body">
|
|
41
133
|
{#if shouldShowErrorMessage(report)}
|
|
42
|
-
<p class="motiongpu-error-message">{report
|
|
134
|
+
<p class="motiongpu-error-message">{resolveDisplayMessage(report)}</p>
|
|
43
135
|
{/if}
|
|
44
136
|
<p class="motiongpu-error-hint">{report.hint}</p>
|
|
45
137
|
</div>
|
|
@@ -87,6 +179,12 @@
|
|
|
87
179
|
<pre>{report.stack.join('\n')}</pre>
|
|
88
180
|
</details>
|
|
89
181
|
{/if}
|
|
182
|
+
{#if report.context}
|
|
183
|
+
<details class="motiongpu-error-details">
|
|
184
|
+
<summary>Runtime context</summary>
|
|
185
|
+
<pre>{formatRuntimeContext(report.context)}</pre>
|
|
186
|
+
</details>
|
|
187
|
+
{/if}
|
|
90
188
|
</div>
|
|
91
189
|
</section>
|
|
92
190
|
</div>
|
|
@@ -162,6 +260,19 @@
|
|
|
162
260
|
border-bottom: 1px solid var(--motiongpu-color-border);
|
|
163
261
|
}
|
|
164
262
|
|
|
263
|
+
.motiongpu-error-header-top {
|
|
264
|
+
display: flex;
|
|
265
|
+
align-items: flex-start;
|
|
266
|
+
gap: 0.75rem;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.motiongpu-error-badges {
|
|
270
|
+
display: inline-flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
gap: 0.4rem;
|
|
273
|
+
flex-wrap: wrap;
|
|
274
|
+
}
|
|
275
|
+
|
|
165
276
|
.motiongpu-error-badge-wrap {
|
|
166
277
|
display: inline-flex;
|
|
167
278
|
align-items: center;
|
|
@@ -173,7 +284,7 @@
|
|
|
173
284
|
background: var(--motiongpu-color-background-muted);
|
|
174
285
|
}
|
|
175
286
|
|
|
176
|
-
.motiongpu-error-
|
|
287
|
+
.motiongpu-error-badge {
|
|
177
288
|
display: inline-flex;
|
|
178
289
|
align-items: center;
|
|
179
290
|
margin: 0;
|
|
@@ -193,6 +304,20 @@
|
|
|
193
304
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);
|
|
194
305
|
}
|
|
195
306
|
|
|
307
|
+
.motiongpu-error-recoverable {
|
|
308
|
+
margin: 0;
|
|
309
|
+
font-size: 0.67rem;
|
|
310
|
+
line-height: 1.2;
|
|
311
|
+
letter-spacing: 0.06em;
|
|
312
|
+
text-transform: uppercase;
|
|
313
|
+
color: var(--motiongpu-color-foreground-muted);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.motiongpu-error-recoverable span {
|
|
317
|
+
font-family: var(--motiongpu-font-mono);
|
|
318
|
+
color: var(--motiongpu-color-foreground);
|
|
319
|
+
}
|
|
320
|
+
|
|
196
321
|
.motiongpu-error-title {
|
|
197
322
|
margin: 0;
|
|
198
323
|
font-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);
|
|
@@ -372,6 +497,11 @@
|
|
|
372
497
|
.motiongpu-error-title {
|
|
373
498
|
font-size: 1.02rem;
|
|
374
499
|
}
|
|
500
|
+
|
|
501
|
+
.motiongpu-error-header-top {
|
|
502
|
+
flex-direction: column;
|
|
503
|
+
align-items: flex-start;
|
|
504
|
+
}
|
|
375
505
|
}
|
|
376
506
|
|
|
377
507
|
@media (prefers-reduced-motion: reduce) {
|
package/src/lib/svelte/index.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { default as FragCanvas } from './FragCanvas.svelte';
|
|
5
5
|
export { defineMaterial } from '../core/material.js';
|
|
6
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
BlitPass,
|
|
8
|
+
CopyPass,
|
|
9
|
+
ShaderPass,
|
|
10
|
+
ComputePass,
|
|
11
|
+
PingPongComputePass
|
|
12
|
+
} from '../passes/index.js';
|
|
7
13
|
export { useMotionGPU } from './motiongpu-context.js';
|
|
8
14
|
export { useFrame } from './frame-context.js';
|
|
9
15
|
export { useTexture } from './use-texture.js';
|
|
@@ -11,6 +17,8 @@ export type {
|
|
|
11
17
|
FrameInvalidationToken,
|
|
12
18
|
FrameState,
|
|
13
19
|
OutputColorSpace,
|
|
20
|
+
AnyPass,
|
|
21
|
+
ComputePassLike,
|
|
14
22
|
RenderPass,
|
|
15
23
|
RenderPassContext,
|
|
16
24
|
RenderPassFlags,
|
|
@@ -49,3 +57,12 @@ export type {
|
|
|
49
57
|
export type { MotionGPUContext } from './motiongpu-context.js';
|
|
50
58
|
export type { UseFrameOptions, UseFrameResult } from './frame-context.js';
|
|
51
59
|
export type { TextureUrlInput, UseTextureResult } from './use-texture.js';
|
|
60
|
+
export type {
|
|
61
|
+
StorageBufferAccess,
|
|
62
|
+
StorageBufferDefinition,
|
|
63
|
+
StorageBufferDefinitionMap,
|
|
64
|
+
StorageBufferType,
|
|
65
|
+
ComputePassContext
|
|
66
|
+
} from '../core/types.js';
|
|
67
|
+
export type { ComputePassOptions, ComputeDispatchContext } from '../passes/ComputePass.js';
|
|
68
|
+
export type { PingPongComputePassOptions } from '../passes/PingPongComputePass.js';
|