@forgeax/engine-render-graph 0.1.2

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 (78) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +184 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/__tests__/graph-pass-kind-owner.test-d.d.ts +2 -0
  5. package/dist/__tests__/graph-pass-kind-owner.test-d.d.ts.map +1 -0
  6. package/dist/__tests__/observation-lifetime-state-owner.test-d.d.ts +2 -0
  7. package/dist/__tests__/observation-lifetime-state-owner.test-d.d.ts.map +1 -0
  8. package/dist/__tests__/observation.unit.test.d.ts +2 -0
  9. package/dist/__tests__/observation.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/render-graph-alias-source.unit.test.d.ts +2 -0
  11. package/dist/__tests__/render-graph-alias-source.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/render-graph-builder.unit.test.d.ts +2 -0
  13. package/dist/__tests__/render-graph-builder.unit.test.d.ts.map +1 -0
  14. package/dist/__tests__/render-graph-capability-owner.test-d.d.ts +2 -0
  15. package/dist/__tests__/render-graph-capability-owner.test-d.d.ts.map +1 -0
  16. package/dist/__tests__/render-graph-errors.test-d.d.ts +2 -0
  17. package/dist/__tests__/render-graph-errors.test-d.d.ts.map +1 -0
  18. package/dist/__tests__/render-graph-regressions.unit.test.d.ts +2 -0
  19. package/dist/__tests__/render-graph-regressions.unit.test.d.ts.map +1 -0
  20. package/dist/__tests__/render-graph-rhi-null.integration.test.d.ts +2 -0
  21. package/dist/__tests__/render-graph-rhi-null.integration.test.d.ts.map +1 -0
  22. package/dist/__tests__/render-graph.unit.test.d.ts +2 -0
  23. package/dist/__tests__/render-graph.unit.test.d.ts.map +1 -0
  24. package/dist/__tests__/resource-declaration-collision.test.d.ts +2 -0
  25. package/dist/__tests__/resource-declaration-collision.test.d.ts.map +1 -0
  26. package/dist/__tests__/resource-kind-owner.test-d.d.ts +2 -0
  27. package/dist/__tests__/resource-kind-owner.test-d.d.ts.map +1 -0
  28. package/dist/builder.d.ts +42 -0
  29. package/dist/builder.d.ts.map +1 -0
  30. package/dist/compiled-graph.d.ts +23 -0
  31. package/dist/compiled-graph.d.ts.map +1 -0
  32. package/dist/errors.d.ts +148 -0
  33. package/dist/errors.d.ts.map +1 -0
  34. package/dist/graph.d.ts +404 -0
  35. package/dist/graph.d.ts.map +1 -0
  36. package/dist/index.d.ts +8 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.mjs +2256 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/kernel-internal.d.ts +84 -0
  41. package/dist/kernel-internal.d.ts.map +1 -0
  42. package/dist/observation.d.ts +38 -0
  43. package/dist/observation.d.ts.map +1 -0
  44. package/dist/pass-registry.d.ts +12 -0
  45. package/dist/pass-registry.d.ts.map +1 -0
  46. package/dist/pipeline/__tests__/color-value-domain.test.d.ts +2 -0
  47. package/dist/pipeline/__tests__/color-value-domain.test.d.ts.map +1 -0
  48. package/dist/pipeline/color-value-domain.d.ts +35 -0
  49. package/dist/pipeline/color-value-domain.d.ts.map +1 -0
  50. package/dist/resource-registry.d.ts +61 -0
  51. package/dist/resource-registry.d.ts.map +1 -0
  52. package/dist/types.d.ts +171 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/package.json +61 -0
  55. package/src/__tests__/graph-pass-kind-owner.test-d.ts +35 -0
  56. package/src/__tests__/observation-lifetime-state-owner.test-d.ts +39 -0
  57. package/src/__tests__/observation.unit.test.ts +103 -0
  58. package/src/__tests__/render-graph-alias-source.unit.test.ts +118 -0
  59. package/src/__tests__/render-graph-builder.unit.test.ts +664 -0
  60. package/src/__tests__/render-graph-capability-owner.test-d.ts +32 -0
  61. package/src/__tests__/render-graph-errors.test-d.ts +169 -0
  62. package/src/__tests__/render-graph-regressions.unit.test.ts +126 -0
  63. package/src/__tests__/render-graph-rhi-null.integration.test.ts +86 -0
  64. package/src/__tests__/render-graph.unit.test.ts +2549 -0
  65. package/src/__tests__/resource-declaration-collision.test.ts +151 -0
  66. package/src/__tests__/resource-kind-owner.test-d.ts +38 -0
  67. package/src/builder.ts +1009 -0
  68. package/src/compiled-graph.ts +383 -0
  69. package/src/errors.ts +205 -0
  70. package/src/graph.ts +1270 -0
  71. package/src/index.ts +97 -0
  72. package/src/kernel-internal.ts +148 -0
  73. package/src/observation.ts +134 -0
  74. package/src/pass-registry.ts +43 -0
  75. package/src/pipeline/__tests__/color-value-domain.test.ts +43 -0
  76. package/src/pipeline/color-value-domain.ts +139 -0
  77. package/src/resource-registry.ts +173 -0
  78. package/src/types.ts +217 -0
@@ -0,0 +1,38 @@
1
+ import type { Texture } from '@forgeax/engine-rhi';
2
+ import { RenderGraphError, type Result } from './errors.js';
3
+ export { RenderGraphError } from './errors.js';
4
+ export interface ObservationSize {
5
+ readonly width: number;
6
+ readonly height: number;
7
+ }
8
+ /** Generic producer-owned metadata for one current-frame texture. */
9
+ export interface CurrentFrameObservationDescriptor {
10
+ readonly texture: Texture;
11
+ readonly format: string;
12
+ readonly size: ObservationSize;
13
+ readonly usage: number;
14
+ readonly frameId: number;
15
+ }
16
+ export interface CurrentFrameObservationLifetime {
17
+ readonly frameId: number;
18
+ readonly state: 'active' | 'retired';
19
+ }
20
+ /** The only resource information a downstream copy consumer receives. */
21
+ export interface CurrentFrameObservationSource {
22
+ readonly texture: Texture;
23
+ readonly descriptor: CurrentFrameObservationDescriptor;
24
+ readonly lifetime: CurrentFrameObservationLifetime;
25
+ }
26
+ export interface CurrentFrameObservationLease {
27
+ readonly descriptor: CurrentFrameObservationDescriptor;
28
+ readonly lifetime: CurrentFrameObservationLifetime;
29
+ readonly state: CurrentFrameObservationLifetime['state'];
30
+ beginReadback(): Result<CurrentFrameObservationSource, RenderGraphError>;
31
+ retire(): void;
32
+ }
33
+ /**
34
+ * Validate and lease a producer's current-frame texture without naming any
35
+ * semantic, pipeline, backend policy, or graph resource key.
36
+ */
37
+ export declare function createCurrentFrameObservationLease(descriptor: CurrentFrameObservationDescriptor, currentFrameId: number): Result<CurrentFrameObservationLease, RenderGraphError>;
38
+ //# sourceMappingURL=observation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAW,gBAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;CACtC;AAED,yEAAyE;AACzE,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,iCAAiC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,+BAA+B,CAAC;CACpD;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,iCAAiC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,+BAA+B,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,CAAC;IACzD,aAAa,IAAI,MAAM,CAAC,6BAA6B,EAAE,gBAAgB,CAAC,CAAC;IACzE,MAAM,IAAI,IAAI,CAAC;CAChB;AAeD;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,UAAU,EAAE,iCAAiC,EAC7C,cAAc,EAAE,MAAM,GACrB,MAAM,CAAC,4BAA4B,EAAE,gBAAgB,CAAC,CAwExD"}
@@ -0,0 +1,12 @@
1
+ import type { PassDescriptor } from './graph.js';
2
+ export interface PassEntry<Ctx = unknown> {
3
+ readonly name: string;
4
+ readonly descriptor: PassDescriptor<Ctx>;
5
+ }
6
+ export declare class PassRegistry<Ctx = unknown> {
7
+ private readonly passes;
8
+ add(name: string, descriptor: PassDescriptor<Ctx>, before?: string): PassEntry<Ctx>;
9
+ list(): readonly PassEntry<Ctx>[];
10
+ count(): number;
11
+ }
12
+ //# sourceMappingURL=pass-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pass-registry.d.ts","sourceRoot":"","sources":["../src/pass-registry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,SAAS,CAAC,GAAG,GAAG,OAAO;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CAC1C;AAED,qBAAa,YAAY,CAAC,GAAG,GAAG,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAE/C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC;IAiBnF,IAAI,IAAI,SAAS,SAAS,CAAC,GAAG,CAAC,EAAE;IAIjC,KAAK,IAAI,MAAM;CAGhB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=color-value-domain.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-value-domain.test.d.ts","sourceRoot":"","sources":["../../../src/pipeline/__tests__/color-value-domain.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { RenderGraphError, type Result } from '../errors.js';
2
+ export declare const COLOR_VALUE_DOMAINS: readonly ["linear-hdr", "linear-ldr", "display-encoded"];
3
+ export type ColorValueDomain = (typeof COLOR_VALUE_DOMAINS)[number];
4
+ export type ColorDomainConversion = {
5
+ readonly kind: 'encode-srgb';
6
+ } | {
7
+ readonly kind: 'decode-srgb';
8
+ } | {
9
+ readonly kind: 'tone-map';
10
+ };
11
+ export interface ColorResourceDescriptor {
12
+ readonly domain: ColorValueDomain;
13
+ readonly format: string;
14
+ }
15
+ export interface ColorDomainConnection {
16
+ readonly source: string;
17
+ readonly destination: string;
18
+ readonly conversion?: ColorDomainConversion | undefined;
19
+ }
20
+ export type ColorDomainValidation = {
21
+ readonly ok: true;
22
+ } | {
23
+ readonly ok: false;
24
+ readonly error: RenderGraphError;
25
+ };
26
+ export declare function isColorValueDomain(value: unknown): value is ColorValueDomain;
27
+ declare function invalidDomain(value: unknown): RenderGraphError;
28
+ declare function missingDomain(resourceKey?: string): RenderGraphError;
29
+ export declare function serializeColorValueDomain(domain: ColorValueDomain): string;
30
+ export declare function deserializeColorValueDomain(value: unknown): Result<ColorValueDomain, RenderGraphError>;
31
+ export declare function serializeColorResourceDescriptor(descriptor: ColorResourceDescriptor): string;
32
+ export declare function deserializeColorResourceDescriptor(value: unknown): Result<ColorResourceDescriptor, RenderGraphError>;
33
+ export declare function validateColorDomainConnection(source: unknown, destination: unknown, conversion?: ColorDomainConversion): ColorDomainValidation;
34
+ export { invalidDomain, missingDomain };
35
+ //# sourceMappingURL=color-value-domain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-value-domain.d.ts","sourceRoot":"","sources":["../../src/pipeline/color-value-domain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,gBAAgB,EAAE,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtE,eAAO,MAAM,mBAAmB,0DAA2D,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;CACzD;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAOvD;AAED,iBAAS,aAAa,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAO7D;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAG1E;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAU5C;AAED,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,uBAAuB,GAAG,MAAM,CAG5F;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAgBnD;AAsBD,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,EACf,WAAW,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,qBAAqB,GACjC,qBAAqB,CAoBvB;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { type CapMissingDetail, type DanglingReadDetail, type DuplicateResourceDetail, RenderGraphError, type Result } from './errors.js';
2
+ import type { ColorTargetDescriptor, ColorTargetSize, ResourceDescriptor, ResourceLifetime } from './graph.js';
3
+ import type { ColorValueDomain } from './pipeline/color-value-domain.js';
4
+ /**
5
+ * Per-resource GPU allocation metadata carried through compile.
6
+ * When the resource was registered via addColorTarget, colorTarget
7
+ * carries the format/size/sample/usage fields (w5); when via
8
+ * addResource it is undefined.
9
+ */
10
+ export interface ColorTargetResourceMeta {
11
+ readonly format: string;
12
+ readonly size: ColorTargetSize;
13
+ readonly sample: number;
14
+ readonly usage: number;
15
+ /** Explicit semantic color domain; never derived from format. */
16
+ readonly domain?: ColorValueDomain | undefined;
17
+ /**
18
+ * Extra texture view formats pre-declared at GPU texture creation. Mirrors
19
+ * GPUTextureDescriptor.viewFormats. Used by the LDR MSAA path which needs a
20
+ * `bgra8unorm` storage texture plus a `bgra8unorm-srgb` view of the same
21
+ * texture for hardware sRGB encoding on store.
22
+ */
23
+ readonly viewFormats?: readonly string[] | undefined;
24
+ /**
25
+ * When set, this resource is an alias of the given source resource.
26
+ * The compile allocation phase folds the alias into the source's
27
+ * physical texture (KB-1 MoveNode pattern, D-2).
28
+ */
29
+ readonly aliasedFrom?: string | undefined;
30
+ }
31
+ export interface ResourceEntry {
32
+ readonly key: string;
33
+ readonly descriptor: ResourceDescriptor;
34
+ readonly lifetime: ResourceLifetime;
35
+ /** Present when the resource was registered via addColorTarget (w5). */
36
+ readonly colorTarget?: ColorTargetResourceMeta | undefined;
37
+ }
38
+ export declare class ResourceRegistry {
39
+ private readonly resources;
40
+ add(key: string, descriptor: ResourceDescriptor): Result<ResourceEntry, RenderGraphError>;
41
+ /**
42
+ * Register a color target resource (D-8).
43
+ * Same semantics as addResource with kind:'texture' plus GPU texture
44
+ * allocation metadata. Existing callers default to a transient target.
45
+ */
46
+ addColorTarget(name: string, desc: ColorTargetDescriptor): Result<ResourceEntry, RenderGraphError>;
47
+ /**
48
+ * Register a color target alias that folds into the source's physical
49
+ * texture at compile time (KB-1 MoveNode pattern, D-2).
50
+ * The source must already be registered via addColorTarget.
51
+ */
52
+ addColorTargetAlias(name: string, source: string): Result<ResourceEntry, RenderGraphError>;
53
+ private duplicateResource;
54
+ private register;
55
+ get(key: string): ResourceEntry | undefined;
56
+ getColorTargetMeta(key: string): ColorTargetResourceMeta | undefined;
57
+ has(key: string): boolean;
58
+ entries(): IterableIterator<ResourceEntry>;
59
+ }
60
+ export type { CapMissingDetail, DanglingReadDetail, DuplicateResourceDetail };
61
+ //# sourceMappingURL=resource-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../src/resource-registry.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAG5B,gBAAgB,EAChB,KAAK,MAAM,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACrD;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAC5D;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAE9D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,GAAG,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC;IASzF;;;;OAIG;IACH,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,qBAAqB,GAC1B,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC;IAmB1C;;;;OAIG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC;IA8B1F,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,QAAQ;IAMhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI3C,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS;IAIpE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,OAAO,IAAI,gBAAgB,CAAC,aAAa,CAAC;CAG3C;AAGD,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,171 @@
1
+ import type { Buffer, ComputePassDescriptor, RhiCommandEncoder, RhiComputePassEncoder, RhiDevice, RhiRenderPassEncoder, Texture, TextureFormat, TextureView } from '@forgeax/engine-rhi';
2
+ import type { RenderGraphError, Result } from './errors.js';
3
+ declare const graphTextureBrand: unique symbol;
4
+ declare const graphTextureViewBrand: unique symbol;
5
+ declare const graphBufferBrand: unique symbol;
6
+ export interface GraphTexture {
7
+ readonly [graphTextureBrand]: true;
8
+ }
9
+ export interface GraphTextureView {
10
+ readonly [graphTextureViewBrand]: true;
11
+ }
12
+ export interface GraphBuffer {
13
+ readonly [graphBufferBrand]: true;
14
+ }
15
+ export type GraphResource = GraphTexture | GraphTextureView | GraphBuffer;
16
+ export type GraphResourceOrigin = 'created' | 'imported';
17
+ export type GraphResourceKind = 'texture' | 'buffer';
18
+ export type GraphExtent = 'surface' | 'half-surface' | {
19
+ readonly width: number;
20
+ readonly height: number;
21
+ readonly depthOrArrayLayers?: number | undefined;
22
+ };
23
+ export interface GraphTextureDescriptor {
24
+ readonly format: TextureFormat;
25
+ readonly size: GraphExtent;
26
+ readonly mipLevelCount?: number | undefined;
27
+ readonly sampleCount?: number | undefined;
28
+ readonly dimension?: GPUTextureDimension | undefined;
29
+ readonly viewFormats?: readonly TextureFormat[] | undefined;
30
+ }
31
+ export interface ImportedTextureDescriptor extends GraphTextureDescriptor {
32
+ readonly usage: number;
33
+ }
34
+ export interface GraphTextureViewDescriptor {
35
+ readonly label?: string | undefined;
36
+ readonly format?: TextureFormat | undefined;
37
+ readonly dimension?: GPUTextureViewDimension | undefined;
38
+ readonly aspect?: GPUTextureAspect | undefined;
39
+ readonly baseMipLevel?: number | undefined;
40
+ readonly mipLevelCount?: number | undefined;
41
+ readonly baseArrayLayer?: number | undefined;
42
+ readonly arrayLayerCount?: number | undefined;
43
+ }
44
+ export type ImportedTextureViewResolver<FrameCtx> = (frame: FrameCtx) => TextureView;
45
+ export interface GraphBufferDescriptor {
46
+ readonly size: number;
47
+ readonly mappedAtCreation?: boolean | undefined;
48
+ }
49
+ export interface ImportedBufferDescriptor extends GraphBufferDescriptor {
50
+ readonly usage: number;
51
+ }
52
+ export type GraphBufferAccess = 'uniform-read' | 'storage-read' | 'storage-write' | 'storage-read-write' | 'indirect-read' | 'vertex-read' | 'index-read' | 'copy-src' | 'copy-dst';
53
+ export type GraphTextureAccess = 'sampled-read' | 'storage-read' | 'storage-write' | 'storage-read-write' | 'color-attachment' | 'depth-stencil-read' | 'depth-stencil-write' | 'copy-src' | 'copy-dst';
54
+ export type GraphAccess = {
55
+ readonly resource: GraphBuffer;
56
+ readonly usage: GraphBufferAccess;
57
+ } | {
58
+ readonly resource: GraphTextureView;
59
+ readonly usage: GraphTextureAccess;
60
+ };
61
+ export interface GraphResourceResolver {
62
+ buffer(resource: GraphBuffer): Result<Buffer, RenderGraphError>;
63
+ texture(resource: GraphTexture): Result<Texture, RenderGraphError>;
64
+ textureView(resource: GraphTextureView): Result<TextureView, RenderGraphError>;
65
+ }
66
+ export interface RasterColorAttachment<FrameCtx> {
67
+ readonly view: GraphTextureView;
68
+ readonly resolveTarget?: GraphTextureView | undefined;
69
+ readonly clearValue?: GPUColor | ((frame: FrameCtx) => GPUColor) | undefined;
70
+ readonly loadOp: GPULoadOp;
71
+ readonly storeOp: GPUStoreOp;
72
+ readonly depthSlice?: number | undefined;
73
+ }
74
+ export interface RasterDepthStencilAttachment {
75
+ readonly view: GraphTextureView;
76
+ readonly depthClearValue?: number | undefined;
77
+ readonly depthLoadOp?: GPULoadOp | undefined;
78
+ readonly depthStoreOp?: GPUStoreOp | undefined;
79
+ readonly depthReadOnly?: boolean | undefined;
80
+ readonly stencilClearValue?: number | undefined;
81
+ readonly stencilLoadOp?: GPULoadOp | undefined;
82
+ readonly stencilStoreOp?: GPUStoreOp | undefined;
83
+ readonly stencilReadOnly?: boolean | undefined;
84
+ }
85
+ export interface RasterGraphPass<FrameCtx> {
86
+ readonly accesses: readonly GraphAccess[];
87
+ readonly colorAttachments: readonly RasterColorAttachment<FrameCtx>[];
88
+ readonly depthStencilAttachment?: RasterDepthStencilAttachment | undefined;
89
+ readonly executeIf?: ((frame: FrameCtx) => boolean) | undefined;
90
+ encode(context: {
91
+ readonly pass: RhiRenderPassEncoder;
92
+ readonly frame: FrameCtx;
93
+ readonly resources: GraphResourceResolver;
94
+ }): void;
95
+ }
96
+ export interface ComputeGraphPass<FrameCtx> {
97
+ readonly accesses: readonly GraphAccess[];
98
+ readonly executeIf?: ((frame: FrameCtx) => boolean) | undefined;
99
+ readonly begin?: ((frame: FrameCtx) => ComputePassDescriptor) | undefined;
100
+ readonly onBeginError?: ((frame: FrameCtx, cause: unknown) => void) | undefined;
101
+ encode(context: {
102
+ readonly pass: RhiComputePassEncoder;
103
+ readonly frame: FrameCtx;
104
+ readonly resources: GraphResourceResolver;
105
+ }): void;
106
+ readonly after?: ((frame: FrameCtx) => void) | undefined;
107
+ }
108
+ export interface CopyGraphPass<FrameCtx> {
109
+ readonly accesses: readonly GraphAccess[];
110
+ readonly executeIf?: ((frame: FrameCtx) => boolean) | undefined;
111
+ encode(context: {
112
+ readonly encoder: RhiCommandEncoder;
113
+ readonly frame: FrameCtx;
114
+ readonly resources: GraphResourceResolver;
115
+ }): void;
116
+ }
117
+ export type GraphPass<FrameCtx> = {
118
+ readonly kind: 'raster';
119
+ readonly descriptor: RasterGraphPass<FrameCtx>;
120
+ } | {
121
+ readonly kind: 'compute';
122
+ readonly descriptor: ComputeGraphPass<FrameCtx>;
123
+ } | {
124
+ readonly kind: 'copy';
125
+ readonly descriptor: CopyGraphPass<FrameCtx>;
126
+ };
127
+ export type GraphPassKind = GraphPass<unknown>['kind'];
128
+ export interface GraphAccessInfo {
129
+ readonly resource: string;
130
+ readonly usage: GraphBufferAccess | GraphTextureAccess;
131
+ }
132
+ export interface CompiledRenderGraphInfo {
133
+ readonly passes: readonly {
134
+ readonly name: string;
135
+ readonly kind: GraphPassKind;
136
+ readonly executionIndex: number;
137
+ readonly accesses: readonly GraphAccessInfo[];
138
+ readonly dependencies: readonly string[];
139
+ }[];
140
+ readonly resources: readonly {
141
+ readonly label: string;
142
+ readonly kind: GraphResourceKind;
143
+ readonly origin: GraphResourceOrigin;
144
+ readonly firstUse: number | null;
145
+ readonly lastUse: number | null;
146
+ readonly derivedUsage: number;
147
+ }[];
148
+ }
149
+ export interface RenderGraphFrame {
150
+ readonly encoder: RhiCommandEncoder;
151
+ }
152
+ export interface RenderGraphPassExecution {
153
+ readonly name: string;
154
+ readonly kind: GraphPassKind;
155
+ readonly executionIndex: number;
156
+ }
157
+ export type RenderGraphPassRunner = (pass: RenderGraphPassExecution, encode: () => void) => void;
158
+ export interface RenderGraphCompileOptions {
159
+ readonly device: RhiDevice;
160
+ readonly surfaceSize: {
161
+ readonly width: number;
162
+ readonly height: number;
163
+ };
164
+ }
165
+ export interface CompiledRenderGraph<FrameCtx extends RenderGraphFrame> {
166
+ execute(frame: FrameCtx, runPass?: RenderGraphPassRunner): Result<void, RenderGraphError>;
167
+ inspect(): CompiledRenderGraphInfo;
168
+ retire(): Promise<Result<void, RenderGraphError>>;
169
+ }
170
+ export {};
171
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@forgeax/engine-render-graph",
3
+ "version": "0.1.2",
4
+ "private": false,
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "sideEffects": false,
8
+ "description": "RHI-pure typed GPU work graph: resource access declaration, immutable compilation, execution, and retirement.",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "main": "./dist/index.mjs",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist",
20
+ "src",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "dependencies": {
25
+ "@forgeax/engine-rhi": "0.1.2",
26
+ "@forgeax/engine-types": "0.1.2",
27
+ "@webgpu/types": "^0.1.71"
28
+ },
29
+ "devDependencies": {
30
+ "@forgeax/engine-rhi-null": "0.1.2"
31
+ },
32
+ "forgeax": {
33
+ "metrics": {
34
+ "bundle-size": {
35
+ "enabled": true,
36
+ "path": "dist/index.mjs",
37
+ "compression": "gzip"
38
+ },
39
+ "fps": {
40
+ "enabled": false,
41
+ "reason": "render-graph is a compile-time / orchestration layer without canvas; fps reported by consuming runtime apps"
42
+ },
43
+ "bench": {
44
+ "enabled": false,
45
+ "reason": "compile path is not perf-critical; bench focus stays on @forgeax/engine-math and runtime render loop"
46
+ },
47
+ "gate": {
48
+ "enabled": false,
49
+ "reason": "physical-isolation grep gate (check-render-graph-no-runtime-import) is a repo-root script wired into ci.yml lint job, not a per-package gate"
50
+ },
51
+ "spike-report": {
52
+ "enabled": false,
53
+ "reason": "not a spike package"
54
+ }
55
+ }
56
+ },
57
+ "scripts": {
58
+ "build": "tsup",
59
+ "test": "vitest run"
60
+ }
61
+ }
@@ -0,0 +1,35 @@
1
+ import { describe, expectTypeOf, it } from 'vitest';
2
+ import type {
3
+ CompiledRenderGraphInfo,
4
+ GraphPass,
5
+ GraphPassKind,
6
+ RenderGraphPassExecution,
7
+ } from '../index.js';
8
+
9
+ type GraphPassKindOwner = GraphPass<unknown>['kind'];
10
+ type ExpectedGraphPassKind = 'raster' | 'compute' | 'copy';
11
+ type CompiledPassKind = CompiledRenderGraphInfo['passes'][number]['kind'];
12
+ type ExecutionPassKind = RenderGraphPassExecution['kind'];
13
+
14
+ describe('render-graph pass kind owner', () => {
15
+ it('keeps the exact raster, compute, and copy membership', () => {
16
+ expectTypeOf<GraphPassKindOwner>().toEqualTypeOf<ExpectedGraphPassKind>();
17
+ expectTypeOf<ExpectedGraphPassKind>().toEqualTypeOf<GraphPassKindOwner>();
18
+ expectTypeOf<GraphPassKind>().toEqualTypeOf<GraphPassKindOwner>();
19
+ expectTypeOf<GraphPassKindOwner>().toEqualTypeOf<GraphPassKind>();
20
+
21
+ const acceptsPassKind = (kind: GraphPassKindOwner): GraphPassKindOwner => kind;
22
+ acceptsPassKind('raster');
23
+ acceptsPassKind('compute');
24
+ acceptsPassKind('copy');
25
+ // @ts-expect-error unknown pass kinds remain outside the closed union.
26
+ acceptsPassKind('pass-kind-not-real');
27
+ });
28
+
29
+ it('keeps compiled and execution views equal to the owner', () => {
30
+ expectTypeOf<CompiledPassKind>().toEqualTypeOf<GraphPassKindOwner>();
31
+ expectTypeOf<GraphPassKindOwner>().toEqualTypeOf<CompiledPassKind>();
32
+ expectTypeOf<ExecutionPassKind>().toEqualTypeOf<GraphPassKindOwner>();
33
+ expectTypeOf<GraphPassKindOwner>().toEqualTypeOf<ExecutionPassKind>();
34
+ });
35
+ });
@@ -0,0 +1,39 @@
1
+ /// <reference types="node" />
2
+
3
+ import { readFileSync } from 'node:fs';
4
+ import { describe, expect, expectTypeOf, it } from 'vitest';
5
+ import type { CurrentFrameObservationLease, CurrentFrameObservationLifetime } from '../index.js';
6
+
7
+ const observationSource = readFileSync(new URL('../observation.ts', import.meta.url), 'utf8');
8
+
9
+ describe('current-frame observation lifetime state owner', () => {
10
+ it('keeps lease state bilaterally equal to the lifetime owner', () => {
11
+ type LifetimeState = CurrentFrameObservationLifetime['state'];
12
+ type LeaseState = CurrentFrameObservationLease['state'];
13
+
14
+ expectTypeOf<LeaseState>().toEqualTypeOf<LifetimeState>();
15
+ expectTypeOf<LifetimeState>().toEqualTypeOf<LeaseState>();
16
+
17
+ const acceptsLifetimeState = (state: LifetimeState): LifetimeState => state;
18
+ const acceptsLeaseState = (state: LeaseState): LeaseState => state;
19
+ acceptsLifetimeState('active');
20
+ acceptsLifetimeState('retired');
21
+ acceptsLeaseState('active');
22
+ acceptsLeaseState('retired');
23
+ // @ts-expect-error unknown observation lifetime states remain outside the closed union.
24
+ acceptsLifetimeState('pending');
25
+ // @ts-expect-error unknown lease states remain outside the closed union.
26
+ acceptsLeaseState('pending');
27
+ });
28
+
29
+ it('keeps the source annotations derived from the lifetime owner', () => {
30
+ expect(observationSource).toContain(
31
+ "readonly state: CurrentFrameObservationLifetime['state'];",
32
+ );
33
+ expect(observationSource).toContain(
34
+ "let state: CurrentFrameObservationLifetime['state'] = 'active';",
35
+ );
36
+ expect(observationSource.match(/readonly state: 'active' \| 'retired';/g)).toHaveLength(1);
37
+ expect(observationSource).not.toContain("let state: 'active' | 'retired' = 'active';");
38
+ });
39
+ });
@@ -0,0 +1,103 @@
1
+ import type { Texture } from '@forgeax/engine-rhi';
2
+ import { describe, expect, it } from 'vitest';
3
+ import {
4
+ type CurrentFrameObservationDescriptor,
5
+ type CurrentFrameObservationLease,
6
+ createCurrentFrameObservationLease,
7
+ RenderGraphError,
8
+ } from '../observation.js';
9
+
10
+ const COPY_SRC = 0x01;
11
+ const RENDER_ATTACHMENT = 0x10;
12
+ const TEXTURE_BINDING = 0x04;
13
+
14
+ const texture = {} as Texture;
15
+
16
+ function descriptor(
17
+ overrides: Partial<CurrentFrameObservationDescriptor> = {},
18
+ ): CurrentFrameObservationDescriptor {
19
+ return {
20
+ texture,
21
+ format: 'rgba16float',
22
+ size: { width: 32, height: 16 },
23
+ usage: RENDER_ATTACHMENT | TEXTURE_BINDING | COPY_SRC,
24
+ frameId: 7,
25
+ ...overrides,
26
+ };
27
+ }
28
+
29
+ function expectError(
30
+ result: { readonly ok: true } | { readonly ok: false; readonly error: { readonly code: string } },
31
+ code: string,
32
+ ): void {
33
+ expect(result.ok).toBe(false);
34
+ if (!result.ok) expect(result.error.code).toBe(code);
35
+ }
36
+
37
+ describe('current-frame observation lease', () => {
38
+ it('accepts an opaque texture descriptor with a fresh frame lifetime', () => {
39
+ const result = createCurrentFrameObservationLease(descriptor(), 7);
40
+
41
+ expect(result.ok).toBe(true);
42
+ if (!result.ok) return;
43
+ expect(result.value.descriptor).toEqual(descriptor());
44
+ expect(result.value.state).toBe('active');
45
+ expect(result.value.beginReadback().ok).toBe(true);
46
+ });
47
+
48
+ it('rejects missing or incompatible observation descriptors', () => {
49
+ expectError(
50
+ createCurrentFrameObservationLease(descriptor({ format: 'bgra8unorm' }), 7),
51
+ 'observation-invalid-format',
52
+ );
53
+ expectError(
54
+ createCurrentFrameObservationLease(descriptor({ size: { width: 0, height: 16 } }), 7),
55
+ 'observation-invalid-size',
56
+ );
57
+ expectError(
58
+ createCurrentFrameObservationLease(descriptor({ usage: RENDER_ATTACHMENT }), 7),
59
+ 'observation-missing-copy-src',
60
+ );
61
+ expectError(
62
+ createCurrentFrameObservationLease(descriptor({ texture: undefined as never }), 7),
63
+ 'observation-absent',
64
+ );
65
+ });
66
+
67
+ it('rejects stale frame descriptors before a lease is created', () => {
68
+ expectError(
69
+ createCurrentFrameObservationLease(descriptor({ frameId: 6 }), 7),
70
+ 'observation-stale',
71
+ );
72
+ });
73
+
74
+ it('fails closed after retirement and exposes no graph key or policy', () => {
75
+ const result = createCurrentFrameObservationLease(descriptor(), 7);
76
+ expect(result.ok).toBe(true);
77
+ if (!result.ok) return;
78
+
79
+ const lease: CurrentFrameObservationLease = result.value;
80
+ lease.retire();
81
+ expect(lease.state).toBe('retired');
82
+ expectError(lease.beginReadback(), 'observation-retired');
83
+ expect('graphKey' in lease).toBe(false);
84
+ expect('pipelineId' in lease).toBe(false);
85
+ expect('backendHandle' in lease).toBe(false);
86
+ });
87
+
88
+ it('keeps the graph package isolated from semantic owners', async () => {
89
+ const source = await import('../observation.js');
90
+ const sourceText = Object.keys(source).join(' ');
91
+ expect(sourceText).not.toMatch(/linear-hdr|URP|HDRP|parity/i);
92
+ });
93
+
94
+ it('uses the structured RenderGraphError surface', () => {
95
+ expect(
96
+ new RenderGraphError({
97
+ code: 'observation-stale',
98
+ expected: 'current frame observation',
99
+ hint: 'capture the current frame before the producer retires it',
100
+ }),
101
+ ).toBeInstanceOf(Error);
102
+ });
103
+ });