@forgeax/engine-rhi-debug 0.1.28 → 0.1.30

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.
Files changed (75) hide show
  1. package/README.md +32 -7
  2. package/dist/__tests__/query-set-lifecycle.unit.test.d.ts +2 -0
  3. package/dist/__tests__/query-set-lifecycle.unit.test.d.ts.map +1 -0
  4. package/dist/__tests__/query-set-replay-fixture.d.ts +39 -0
  5. package/dist/__tests__/query-set-replay-fixture.d.ts.map +1 -0
  6. package/dist/__tests__/recorder-canvas-context.unit.test.d.ts +2 -0
  7. package/dist/__tests__/recorder-canvas-context.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/timestamp-query-capture.dawn.test.d.ts +2 -0
  9. package/dist/__tests__/timestamp-query-capture.dawn.test.d.ts.map +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.mjs +527 -58
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/protocol/event-semantics.d.ts +1 -1
  15. package/dist/protocol/event-semantics.d.ts.map +1 -1
  16. package/dist/protocol/types.d.ts +1 -1
  17. package/dist/protocol/types.d.ts.map +1 -1
  18. package/dist/recorder/closure.d.ts.map +1 -1
  19. package/dist/recorder/core.d.ts +10 -1
  20. package/dist/recorder/core.d.ts.map +1 -1
  21. package/dist/recorder/device.d.ts.map +1 -1
  22. package/dist/recorder/encoder.d.ts.map +1 -1
  23. package/dist/recorder/pass.d.ts.map +1 -1
  24. package/dist/recorder/pipeline.d.ts +5 -0
  25. package/dist/recorder/pipeline.d.ts.map +1 -0
  26. package/dist/recorder/proxy.d.ts +3 -1
  27. package/dist/recorder/proxy.d.ts.map +1 -1
  28. package/dist/recorder/session.d.ts +1 -1
  29. package/dist/recorder/session.d.ts.map +1 -1
  30. package/dist/recorder/shader.d.ts +3 -1
  31. package/dist/recorder/shader.d.ts.map +1 -1
  32. package/dist/recorder.d.ts +2 -2
  33. package/dist/recorder.d.ts.map +1 -1
  34. package/dist/replay/execute.d.ts.map +1 -1
  35. package/dist/replay/resources.d.ts +4 -1
  36. package/dist/replay/resources.d.ts.map +1 -1
  37. package/dist/replay/session.d.ts +7 -0
  38. package/dist/replay/session.d.ts.map +1 -1
  39. package/dist/types.d.ts +45 -6
  40. package/dist/types.d.ts.map +1 -1
  41. package/package.json +6 -6
  42. package/src/__tests__/coverage-invariant.test-d.ts +4 -5
  43. package/src/__tests__/coverage-invariant.unit.test.ts +6 -17
  44. package/src/__tests__/e2e.browser.test.ts +50 -0
  45. package/src/__tests__/guard-gates.test.ts +1 -1
  46. package/src/__tests__/query-set-lifecycle.unit.test.ts +265 -0
  47. package/src/__tests__/query-set-replay-fixture.ts +553 -0
  48. package/src/__tests__/readback-format-matrix.dawn.test.ts +9 -2
  49. package/src/__tests__/recorder-canvas-context.unit.test.ts +67 -0
  50. package/src/__tests__/recorder-session.integration.test.ts +55 -0
  51. package/src/__tests__/recorder-session.unit.test.ts +18 -1
  52. package/src/__tests__/replay-session.dawn.test.ts +171 -0
  53. package/src/__tests__/replay-session.test-d.ts +1 -0
  54. package/src/__tests__/rhi-debug-fresh-replay.dawn.test.ts +61 -0
  55. package/src/__tests__/timestamp-query-capture.dawn.test.ts +61 -0
  56. package/src/index.ts +1 -0
  57. package/src/protocol/event-semantics.ts +21 -2
  58. package/src/protocol/types.ts +1 -0
  59. package/src/protocol/validation.ts +36 -0
  60. package/src/recorder/assemble.ts +8 -1
  61. package/src/recorder/closure.ts +21 -1
  62. package/src/recorder/core.ts +11 -0
  63. package/src/recorder/device.ts +33 -6
  64. package/src/recorder/encoder.ts +60 -6
  65. package/src/recorder/pass.ts +7 -2
  66. package/src/recorder/pipeline.ts +31 -0
  67. package/src/recorder/proxy.ts +58 -2
  68. package/src/recorder/session.ts +1 -1
  69. package/src/recorder/shader.ts +29 -22
  70. package/src/recorder.ts +6 -2
  71. package/src/replay/execute.ts +143 -1
  72. package/src/replay/readback.ts +15 -3
  73. package/src/replay/resources.ts +6 -0
  74. package/src/replay/session.ts +241 -27
  75. package/src/types.ts +61 -14
package/README.md CHANGED
@@ -75,6 +75,13 @@ The host supplies the real RHI backend and owns the file write. The package
75
75
  owns recording, encoding, decoding, replay, and readback contracts. Expected
76
76
  failures are `Result` values, not message-parsed exceptions.
77
77
 
78
+ Recorder attachment preserves both the asynchronous shader factory and an
79
+ optional `createShaderModuleImmediate` factory on the explicit RHI backend.
80
+ Pipeline handles retain native identity. Calls to `getBindGroupLayout(index)`
81
+ record the originating pipeline and index, so automatic layouts participate in
82
+ bootstrap dependency closure and are recovered from the recreated pipeline
83
+ during replay.
84
+
78
85
  ## v7 tape rules
79
86
 
80
87
  The decoder accepts only the current single-file format:
@@ -101,13 +108,22 @@ views aligned.
101
108
 
102
109
  ## Replay and readback
103
110
 
104
- `openReplay` requires a `ReplayBackend` factory. The factory is called only for
105
- the requested operation and must return a fresh backend. `ResourceTable` owns
106
- typed handle generations and disposal; stale generations fail closed. The
107
- readback matrix is explicit: supported color/depth formats use the backend
108
- path, unsupported formats return `readback-unsupported`, and transfer or map
109
- failures return `readback-failed`. Every successful session and every failed
110
- setup path releases backend resources before returning.
111
+ `openReplay(tape, backend)` uses the caller's fresh device and shader factory.
112
+ `ResourceTable` owns replay resources and typed handle generations; stale
113
+ generations fail closed. Session disposal releases replay resources; the
114
+ supplied backend remains owned by its caller.
115
+
116
+ `inspectWork(..., ['pixels'])` reads the first color attachment's resolve target
117
+ when present, after finishing the selected work's pass. Direct reads of an
118
+ unresolved multisampled texture return `readback-unsupported` before any copy.
119
+ The remaining readback matrix is explicit: supported color/depth formats use
120
+ the backend path, unsupported formats return `readback-unsupported`, and
121
+ transfer or map failures return `readback-failed`.
122
+ `readResource(resourceId, subresource)` reads the captured initial state.
123
+ `readResourceAtWork(resourceId, workIndex, subresource)` replays through the
124
+ selected work before reading, including compute storage outputs. Its
125
+ `provenance.selectedWorkIndex` identifies that post-work state. Use this form
126
+ when checking what a dispatch produced; initial bytes are not output evidence.
111
127
 
112
128
  ## Structured errors
113
129
 
@@ -176,3 +192,12 @@ FORGEAX_SKIP_HARNESS_SYNC=1 pnpm --filter @forgeax/engine-rhi-debug build
176
192
  Browser and Dawn gates belong to the host and application packages. They must
177
193
  exercise the same `.rhitape` bytes and the same `workIndex` used by offline
178
194
  inspection.
195
+
196
+ ### Timestamp-bearing frame capture
197
+
198
+ Render, compute and empty-compute pass timestamps retain their QuerySet handle
199
+ identity in v7 events. Capture closure includes a QuerySet created before the
200
+ capture window; validation and resource lineage treat it as a referenced
201
+ resource. Replay replaces its serialized descriptor object with the fresh
202
+ device's QuerySet while preserving beginning/end indices. A missing identity
203
+ is a structured replay failure, never a request to silently remove timestamps.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=query-set-lifecycle.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-set-lifecycle.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/query-set-lifecycle.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ import type { RhiDevice } from '@forgeax/engine-rhi';
2
+ import type { CreateShaderModuleFn, EncodedTape } from '../recorder';
3
+ export type QuerySetFixtureRunner = 'browser' | 'dawn';
4
+ export interface QuerySetFixtureHost {
5
+ readonly runner: QuerySetFixtureRunner;
6
+ readonly device: RhiDevice;
7
+ readonly createShaderModule: CreateShaderModuleFn;
8
+ readonly replayCreateShaderModule: CreateShaderModuleFn;
9
+ readonly finishCapture: () => Promise<EncodedTape>;
10
+ readonly createFreshDevice: () => Promise<RhiDevice>;
11
+ }
12
+ export interface QuerySetErrorReceipt {
13
+ readonly operation: string;
14
+ readonly code: string;
15
+ readonly expected: string;
16
+ readonly hint: string;
17
+ readonly detail: unknown;
18
+ }
19
+ export interface QuerySetReplayFixtureEvidence {
20
+ readonly runner: QuerySetFixtureRunner;
21
+ readonly status: 'available' | 'unavailable' | 'failed';
22
+ readonly tapeFormatVersion: number | null;
23
+ readonly querySetHandleId: string | null;
24
+ readonly resolveDestinationHandleId: string | null;
25
+ readonly resolveDestinationOffset: number | null;
26
+ readonly originalQueryValues: readonly string[];
27
+ readonly originalResultHalfWords: readonly number[];
28
+ readonly freshQueryValues: readonly string[];
29
+ readonly originalColorBytes: readonly number[];
30
+ readonly freshColorHalfWords: readonly number[];
31
+ readonly eventKinds: readonly string[];
32
+ readonly errorReceipts: readonly QuerySetErrorReceipt[];
33
+ readonly deviceLost: {
34
+ readonly reason: string;
35
+ readonly message: string;
36
+ } | null;
37
+ }
38
+ export declare function runQuerySetReplayFixture(host: QuerySetFixtureHost): Promise<QuerySetReplayFixtureEvidence>;
39
+ //# sourceMappingURL=query-set-replay-fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-set-replay-fixture.d.ts","sourceRoot":"","sources":["../../src/__tests__/query-set-replay-fixture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAI3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGrE,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;IAClD,QAAQ,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;IACxD,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IACnD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;IACxD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,uBAAuB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpD,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAubD,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,6BAA6B,CAAC,CAoExC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=recorder-canvas-context.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder-canvas-context.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/recorder-canvas-context.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=timestamp-query-capture.dawn.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestamp-query-capture.dawn.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/timestamp-query-capture.dawn.test.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export { buildTapeIndex } from './protocol/tape-index';
9
9
  export type { BootstrapResource, InitialDataSlice, RhiCallEvent as V7RhiCallEvent, RhiCapsRecorded as V7RhiCapsRecorded, RhiDebugResult, Tape as V7Tape, TapeBlob as V7TapeBlob, TapeBlobCompression, TapeEncodeOptions, } from './protocol/types';
10
10
  export { TAPE_FORMAT_VERSION as V7_TAPE_FORMAT_VERSION, TAPE_MAGIC, } from './protocol/types';
11
11
  export { readbackTexturePixels } from './readback';
12
- export { attachRecorder, type CaptureFrameOptions, type CreateShaderModuleFn, type EncodedTape, type RecordableBackend, type RecorderAttachment, type RecorderBackend, type RecorderOptions, } from './recorder/session';
12
+ export { attachRecorder, type CaptureFrameOptions, type CreateShaderModuleFn, type CreateShaderModuleImmediateFn, type EncodedTape, type RecordableBackend, type RecorderAttachment, type RecorderBackend, type RecorderOptions, } from './recorder/session';
13
13
  export { replayDeviceRequest } from './replay/device-request';
14
14
  export { type InspectField, openReplay, type ReadbackSubresource, type ReplayBackend, type ReplayReadbackResult, type ReplaySession, type TextureSubresource, type WorkInspection, } from './replay/session';
15
15
  export { decodeTexelRaw, decodeToRgba8, halfToFloat } from './texel-decode';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EACL,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,IAAI,cAAc,EAC9B,eAAe,IAAI,iBAAiB,EACpC,cAAc,EACd,IAAI,IAAI,MAAM,EACd,QAAQ,IAAI,UAAU,EACtB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,IAAI,sBAAsB,EAC7C,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EACL,KAAK,YAAY,EACjB,UAAU,EACV,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,YAAY,EACZ,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EACL,eAAe,EACf,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,IAAI,cAAc,EAC9B,eAAe,IAAI,iBAAiB,EACpC,cAAc,EACd,IAAI,IAAI,MAAM,EACd,QAAQ,IAAI,UAAU,EACtB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,IAAI,sBAAsB,EAC7C,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,6BAA6B,EAClC,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EACL,KAAK,YAAY,EACjB,UAAU,EACV,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC"}