@forgeax/engine-rhi-debug 0.1.34 → 0.1.35
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 +2 -0
- package/dist/index.mjs +38 -0
- package/dist/index.mjs.map +1 -1
- package/dist/replay/session.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/e2e.browser.test.ts +6 -0
- package/src/__tests__/rhi-debug-fresh-replay.dawn.test.ts +7 -1
- package/src/replay/session.ts +52 -0
|
@@ -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.35",
|
|
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.35",
|
|
30
|
+
"@forgeax/engine-types": "0.1.35",
|
|
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.35",
|
|
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.35",
|
|
41
|
+
"@forgeax/engine-rhi-wgpu": "0.1.35"
|
|
42
42
|
},
|
|
43
43
|
"forgeax": {
|
|
44
44
|
"metrics": {
|
|
@@ -142,6 +142,7 @@ async function captureBrowserTape(): Promise<CapturedBrowserTape> {
|
|
|
142
142
|
'write source texture',
|
|
143
143
|
);
|
|
144
144
|
const encoder = must(device.createCommandEncoder({}), 'create command encoder');
|
|
145
|
+
encoder.pushDebugGroup('frame');
|
|
145
146
|
const pass = encoder.beginRenderPass({
|
|
146
147
|
colorAttachments: [
|
|
147
148
|
{
|
|
@@ -154,8 +155,13 @@ async function captureBrowserTape(): Promise<CapturedBrowserTape> {
|
|
|
154
155
|
} as never);
|
|
155
156
|
pass.setPipeline(pipeline);
|
|
156
157
|
pass.setBindGroup(0, bindGroup, []);
|
|
158
|
+
pass.pushDebugGroup('outer');
|
|
159
|
+
pass.pushDebugGroup('inner');
|
|
157
160
|
pass.draw(3, 1, 0, 0);
|
|
161
|
+
pass.popDebugGroup();
|
|
162
|
+
pass.popDebugGroup();
|
|
158
163
|
pass.end();
|
|
164
|
+
encoder.popDebugGroup();
|
|
159
165
|
const command = must(encoder.finish(), 'finish command encoder');
|
|
160
166
|
must(device.queue.submit([command]), 'submit command buffer');
|
|
161
167
|
await device.queue.onSubmittedWorkDone();
|
|
@@ -103,6 +103,7 @@ async function makeRecording(pack: DawnPack): Promise<{
|
|
|
103
103
|
const encoderResult = device.createCommandEncoder({});
|
|
104
104
|
expect(encoderResult.ok).toBe(true);
|
|
105
105
|
if (!encoderResult.ok) throw new Error(encoderResult.error.hint);
|
|
106
|
+
encoderResult.value.pushDebugGroup('frame');
|
|
106
107
|
const pass = encoderResult.value.beginRenderPass({
|
|
107
108
|
colorAttachments: [
|
|
108
109
|
{
|
|
@@ -114,8 +115,13 @@ async function makeRecording(pack: DawnPack): Promise<{
|
|
|
114
115
|
],
|
|
115
116
|
} as never);
|
|
116
117
|
pass.setPipeline(pipeline.value);
|
|
118
|
+
pass.pushDebugGroup('outer');
|
|
119
|
+
pass.pushDebugGroup('inner');
|
|
117
120
|
pass.draw(3, 1, 0, 0);
|
|
121
|
+
pass.popDebugGroup();
|
|
122
|
+
pass.popDebugGroup();
|
|
118
123
|
pass.end();
|
|
124
|
+
encoderResult.value.popDebugGroup();
|
|
119
125
|
const command = encoderResult.value.finish();
|
|
120
126
|
expect(command.ok).toBe(true);
|
|
121
127
|
if (!command.ok) throw new Error(command.error.hint);
|
|
@@ -127,7 +133,7 @@ async function makeRecording(pack: DawnPack): Promise<{
|
|
|
127
133
|
}
|
|
128
134
|
|
|
129
135
|
describe.skipIf(SKIP_DAWN)('RHI debug v7 fresh-device evidence', () => {
|
|
130
|
-
it('records, encodes, strictly decodes, and replays pixels on a fresh Dawn device', async () => {
|
|
136
|
+
it('records, encodes, strictly decodes, and replays pixels through nested debug groups on a fresh Dawn device', async () => {
|
|
131
137
|
const pack = await loadDawn();
|
|
132
138
|
const recording = await makeRecording(pack);
|
|
133
139
|
const baseline = await readbackTexturePixels(
|
package/src/replay/session.ts
CHANGED
|
@@ -594,6 +594,13 @@ async function finalizeWorkPass(
|
|
|
594
594
|
finishEventIndex ?? context.tape.events.length,
|
|
595
595
|
);
|
|
596
596
|
if (!closure.ok) return closure;
|
|
597
|
+
const groupsClosed = closeReplayDebugGroups(
|
|
598
|
+
context,
|
|
599
|
+
begin.cmdHandleId,
|
|
600
|
+
work.eventIndex,
|
|
601
|
+
encoder.resource.value as RhiCommandEncoder,
|
|
602
|
+
);
|
|
603
|
+
if (!groupsClosed.ok) return groupsClosed;
|
|
597
604
|
const finished = (encoder.resource.value as RhiCommandEncoder).finish();
|
|
598
605
|
const finishEvent = context.tape.events[finishEventIndex ?? work.eventIndex] ?? begin;
|
|
599
606
|
if (!finished.ok)
|
|
@@ -656,6 +663,15 @@ function closeReplayPass(
|
|
|
656
663
|
);
|
|
657
664
|
}
|
|
658
665
|
}
|
|
666
|
+
if (entry.resource.role === 'render-pass') {
|
|
667
|
+
const groupsClosed = closeReplayDebugGroups(
|
|
668
|
+
context,
|
|
669
|
+
begin.passHandleId,
|
|
670
|
+
selectedEventIndex,
|
|
671
|
+
entry.resource.value as RhiRenderPassEncoder,
|
|
672
|
+
);
|
|
673
|
+
if (!groupsClosed.ok) return groupsClosed;
|
|
674
|
+
}
|
|
659
675
|
(entry.resource.value as RhiRenderPassEncoder | RhiComputePassEncoder).end();
|
|
660
676
|
} catch (cause) {
|
|
661
677
|
return eventFailure(pass.endEventIndex ?? selectedEventIndex, begin, 'encode', cause);
|
|
@@ -664,6 +680,42 @@ function closeReplayPass(
|
|
|
664
680
|
return ok(undefined);
|
|
665
681
|
}
|
|
666
682
|
|
|
683
|
+
// Inspection stops at the selected work, before the recorded scope exits.
|
|
684
|
+
// Derive only the still-open scopes from that prefix; never execute later work.
|
|
685
|
+
function closeReplayDebugGroups(
|
|
686
|
+
context: ReplayExecutionContext,
|
|
687
|
+
handleId: string,
|
|
688
|
+
throughEventIndex: number,
|
|
689
|
+
encoder: RhiCommandEncoder | RhiRenderPassEncoder,
|
|
690
|
+
): Result<void, RhiDebugError> {
|
|
691
|
+
const open: { event: RhiCallEvent; eventIndex: number }[] = [];
|
|
692
|
+
for (let eventIndex = 0; eventIndex <= throughEventIndex; eventIndex++) {
|
|
693
|
+
const event = context.tape.events[eventIndex];
|
|
694
|
+
if (event === undefined) continue;
|
|
695
|
+
if (
|
|
696
|
+
(event.kind === 'pushDebugGroup' && event.cmdHandleId === handleId) ||
|
|
697
|
+
(event.kind === 'passPushDebugGroup' && event.passHandleId === handleId)
|
|
698
|
+
) {
|
|
699
|
+
open.push({ event, eventIndex });
|
|
700
|
+
} else if (
|
|
701
|
+
(event.kind === 'popDebugGroup' && event.cmdHandleId === handleId) ||
|
|
702
|
+
(event.kind === 'passPopDebugGroup' && event.passHandleId === handleId)
|
|
703
|
+
) {
|
|
704
|
+
open.pop();
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
for (let index = open.length - 1; index >= 0; index--) {
|
|
708
|
+
const scope = open[index];
|
|
709
|
+
if (scope === undefined) continue;
|
|
710
|
+
try {
|
|
711
|
+
encoder.popDebugGroup();
|
|
712
|
+
} catch (cause) {
|
|
713
|
+
return eventFailure(scope.eventIndex, scope.event, 'encode', cause);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return ok(undefined);
|
|
717
|
+
}
|
|
718
|
+
|
|
667
719
|
async function replayCommandClosure(
|
|
668
720
|
context: ReplayExecutionContext,
|
|
669
721
|
cmdHandleId: string,
|