@forgeax/engine-rhi-debug 0.1.7 → 0.1.19
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/replay/session.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/replay/session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-rhi-debug",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -26,19 +26,19 @@
|
|
|
26
26
|
"LICENSE"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@forgeax/engine-rhi": "0.1.
|
|
30
|
-
"@forgeax/engine-types": "0.1.
|
|
29
|
+
"@forgeax/engine-rhi": "0.1.19",
|
|
30
|
+
"@forgeax/engine-types": "0.1.19",
|
|
31
31
|
"@noble/hashes": "^2.2.0",
|
|
32
32
|
"pako": "^1.0.11"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@forgeax/engine-rhi-null": "0.1.
|
|
35
|
+
"@forgeax/engine-rhi-null": "0.1.19",
|
|
36
36
|
"@types/node": "^20.14.0",
|
|
37
37
|
"@webgpu/types": "^0.1.71"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@forgeax/engine-rhi-webgpu": "0.1.
|
|
41
|
-
"@forgeax/engine-rhi-wgpu": "0.1.
|
|
40
|
+
"@forgeax/engine-rhi-webgpu": "0.1.19",
|
|
41
|
+
"@forgeax/engine-rhi-wgpu": "0.1.19"
|
|
42
42
|
},
|
|
43
43
|
"forgeax": {
|
|
44
44
|
"metrics": {
|
|
@@ -45,6 +45,57 @@ async function makeBackend(): Promise<ReplayBackend> {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
describe('ReplaySession', () => {
|
|
48
|
+
it('does not require unused recorded optional capabilities', async () => {
|
|
49
|
+
const result = await openReplay(
|
|
50
|
+
{
|
|
51
|
+
...makeWorkTape(),
|
|
52
|
+
header: {
|
|
53
|
+
...makeWorkTape().header,
|
|
54
|
+
rhiCaps: {
|
|
55
|
+
rgba16floatRenderable: true,
|
|
56
|
+
float32Filterable: true,
|
|
57
|
+
textureCompressionBc: true,
|
|
58
|
+
textureCompressionEtc2: true,
|
|
59
|
+
textureCompressionAstc: true,
|
|
60
|
+
storageBuffer: true,
|
|
61
|
+
timestampQuery: true,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
await makeBackend(),
|
|
66
|
+
);
|
|
67
|
+
expect(result.ok).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('requires a recorded compression capability when the tape uses its format', async () => {
|
|
71
|
+
const result = await openReplay(
|
|
72
|
+
{
|
|
73
|
+
header: {
|
|
74
|
+
formatVersion: 7,
|
|
75
|
+
rhiCaps: { textureCompressionBc: true },
|
|
76
|
+
eventCount: 1,
|
|
77
|
+
blobCount: 0,
|
|
78
|
+
},
|
|
79
|
+
bootstrap: [],
|
|
80
|
+
events: [
|
|
81
|
+
{
|
|
82
|
+
kind: 'createTexture',
|
|
83
|
+
handleId: 'texture:compressed',
|
|
84
|
+
desc: {
|
|
85
|
+
size: { width: 4, height: 4, depthOrArrayLayers: 1 },
|
|
86
|
+
format: 'bc1-rgba-unorm',
|
|
87
|
+
usage: 0x04,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
blobs: [],
|
|
92
|
+
},
|
|
93
|
+
await makeBackend(),
|
|
94
|
+
);
|
|
95
|
+
expect(result.ok).toBe(false);
|
|
96
|
+
if (!result.ok) expect(result.error.code).toBe('replay-capability-mismatch');
|
|
97
|
+
});
|
|
98
|
+
|
|
48
99
|
it('replays a depth-only render pipeline without requiring a fragment shader', async () => {
|
|
49
100
|
const tape: Tape = {
|
|
50
101
|
header: { formatVersion: 7, rhiCaps: {}, eventCount: 7, blobCount: 0 },
|
package/src/replay/session.ts
CHANGED
|
@@ -218,8 +218,13 @@ export async function openReplay(
|
|
|
218
218
|
|
|
219
219
|
function checkCapabilities(tape: Tape, device: RhiDevice): RhiDebugError | undefined {
|
|
220
220
|
const recorded = tape.header.rhiCaps;
|
|
221
|
+
const required = requiredReplayCapabilities(tape);
|
|
221
222
|
const missing = Object.entries(recorded).filter(([key, value]) => {
|
|
222
|
-
|
|
223
|
+
// A recorder snapshots the device's available capabilities, but replay
|
|
224
|
+
// only needs to require a capability when the captured workload can use
|
|
225
|
+
// it. Otherwise a device-wide optional feature (for example ASTC support)
|
|
226
|
+
// makes an unrelated RGBA tape non-portable.
|
|
227
|
+
if (value !== true || (!required.has(key) && isKnownReplayCapability(key))) return false;
|
|
223
228
|
const target = device.caps[key as keyof typeof device.caps];
|
|
224
229
|
return target !== true;
|
|
225
230
|
});
|
|
@@ -230,6 +235,93 @@ function checkCapabilities(tape: Tape, device: RhiDevice): RhiDebugError | undef
|
|
|
230
235
|
});
|
|
231
236
|
}
|
|
232
237
|
|
|
238
|
+
const BC_TEXTURE_FORMATS = new Set([
|
|
239
|
+
'bc1-rgba-unorm',
|
|
240
|
+
'bc1-rgba-unorm-srgb',
|
|
241
|
+
'bc2-rgba-unorm',
|
|
242
|
+
'bc2-rgba-unorm-srgb',
|
|
243
|
+
'bc3-rgba-unorm',
|
|
244
|
+
'bc3-rgba-unorm-srgb',
|
|
245
|
+
'bc4-r-unorm',
|
|
246
|
+
'bc4-r-snorm',
|
|
247
|
+
'bc5-rg-unorm',
|
|
248
|
+
'bc5-rg-snorm',
|
|
249
|
+
'bc6h-rgb-ufloat',
|
|
250
|
+
'bc6h-rgb-sfloat',
|
|
251
|
+
'bc7-rgba-unorm',
|
|
252
|
+
'bc7-rgba-unorm-srgb',
|
|
253
|
+
]);
|
|
254
|
+
|
|
255
|
+
const ETC2_TEXTURE_FORMATS = new Set([
|
|
256
|
+
'etc2-rgb8unorm',
|
|
257
|
+
'etc2-rgb8unorm-srgb',
|
|
258
|
+
'etc2-rgb8a1unorm',
|
|
259
|
+
'etc2-rgb8a1unorm-srgb',
|
|
260
|
+
'etc2-rgba8unorm',
|
|
261
|
+
'etc2-rgba8unorm-srgb',
|
|
262
|
+
'eac-r11unorm',
|
|
263
|
+
'eac-r11snorm',
|
|
264
|
+
'eac-rg11unorm',
|
|
265
|
+
'eac-rg11snorm',
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
const KNOWN_REPLAY_CAPABILITIES = new Set([
|
|
269
|
+
'rgba16floatRenderable',
|
|
270
|
+
'float32Filterable',
|
|
271
|
+
'textureCompressionBc',
|
|
272
|
+
'textureCompressionEtc2',
|
|
273
|
+
'textureCompressionAstc',
|
|
274
|
+
'storageBuffer',
|
|
275
|
+
'timestampQuery',
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
function isKnownReplayCapability(key: string): boolean {
|
|
279
|
+
return KNOWN_REPLAY_CAPABILITIES.has(key);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function requiredReplayCapabilities(tape: Tape): ReadonlySet<string> {
|
|
283
|
+
const required = new Set<string>();
|
|
284
|
+
const events = [
|
|
285
|
+
...tape.bootstrap.map((resource) => resource.create as unknown as RhiCallEvent),
|
|
286
|
+
...tape.events,
|
|
287
|
+
];
|
|
288
|
+
for (const event of events) {
|
|
289
|
+
switch (event.kind) {
|
|
290
|
+
case 'createTexture': {
|
|
291
|
+
const formats = [event.desc.format, ...(event.desc.viewFormats ?? [])];
|
|
292
|
+
for (const format of formats) {
|
|
293
|
+
if (BC_TEXTURE_FORMATS.has(format)) required.add('textureCompressionBc');
|
|
294
|
+
if (ETC2_TEXTURE_FORMATS.has(format)) required.add('textureCompressionEtc2');
|
|
295
|
+
if (format.startsWith('astc-')) required.add('textureCompressionAstc');
|
|
296
|
+
if (format === 'rgba16float') required.add('rgba16floatRenderable');
|
|
297
|
+
if (format === 'r32float' || format === 'rg32float' || format === 'rgba32float') {
|
|
298
|
+
required.add('float32Filterable');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case 'createBindGroupLayout':
|
|
304
|
+
if (
|
|
305
|
+
Array.from(event.desc.entries).some(
|
|
306
|
+
(entry) =>
|
|
307
|
+
entry.buffer?.type === 'storage' || entry.buffer?.type === 'read-only-storage',
|
|
308
|
+
)
|
|
309
|
+
) {
|
|
310
|
+
required.add('storageBuffer');
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
case 'createBuffer':
|
|
314
|
+
// GPUBufferUsage.STORAGE is 0x80 in the WebGPU enum. Keep the replay
|
|
315
|
+
// package independent of the browser-only global constant.
|
|
316
|
+
if ((event.desc.usage & 0x80) !== 0) required.add('storageBuffer');
|
|
317
|
+
break;
|
|
318
|
+
default:
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return required;
|
|
323
|
+
}
|
|
324
|
+
|
|
233
325
|
async function executeBootstrapResource(
|
|
234
326
|
context: ReplayExecutionContext,
|
|
235
327
|
resource: BootstrapResource,
|