@aardworx/wombat.rendering 0.8.1 → 0.9.1
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/dist/core/command.d.ts +7 -9
- package/dist/core/command.d.ts.map +1 -1
- package/dist/core/renderTask.d.ts +64 -1
- package/dist/core/renderTask.d.ts.map +1 -1
- package/dist/core/renderTask.js +3 -1
- package/dist/core/renderTask.js.map +1 -1
- package/dist/resources/preparedRenderObject.js +3 -3
- package/dist/resources/preparedRenderObject.js.map +1 -1
- package/dist/resources/uniformBuffer.d.ts.map +1 -1
- package/dist/resources/uniformBuffer.js +17 -0
- package/dist/resources/uniformBuffer.js.map +1 -1
- package/dist/runtime/derivedUniforms/dispatch.d.ts +105 -0
- package/dist/runtime/derivedUniforms/dispatch.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/dispatch.js +355 -0
- package/dist/runtime/derivedUniforms/dispatch.js.map +1 -0
- package/dist/runtime/derivedUniforms/index.d.ts +6 -0
- package/dist/runtime/derivedUniforms/index.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/index.js +26 -0
- package/dist/runtime/derivedUniforms/index.js.map +1 -0
- package/dist/runtime/derivedUniforms/recipes.d.ts +42 -0
- package/dist/runtime/derivedUniforms/recipes.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/recipes.js +134 -0
- package/dist/runtime/derivedUniforms/recipes.js.map +1 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.d.ts +56 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.js +171 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.js.map +1 -0
- package/dist/runtime/derivedUniforms/slotId.d.ts +15 -0
- package/dist/runtime/derivedUniforms/slotId.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/slotId.js +30 -0
- package/dist/runtime/derivedUniforms/slotId.js.map +1 -0
- package/dist/runtime/derivedUniforms/slots.d.ts +49 -0
- package/dist/runtime/derivedUniforms/slots.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/slots.js +123 -0
- package/dist/runtime/derivedUniforms/slots.js.map +1 -0
- package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts +13 -0
- package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/uberKernel.wgsl.js +218 -0
- package/dist/runtime/derivedUniforms/uberKernel.wgsl.js.map +1 -0
- package/dist/runtime/flattenTree.d.ts +5 -0
- package/dist/runtime/flattenTree.d.ts.map +1 -0
- package/dist/runtime/flattenTree.js +45 -0
- package/dist/runtime/flattenTree.js.map +1 -0
- package/dist/runtime/heapAdapter.d.ts +16 -0
- package/dist/runtime/heapAdapter.d.ts.map +1 -0
- package/dist/runtime/heapAdapter.js +263 -0
- package/dist/runtime/heapAdapter.js.map +1 -0
- package/dist/runtime/heapEffect.d.ts +235 -0
- package/dist/runtime/heapEffect.d.ts.map +1 -0
- package/dist/runtime/heapEffect.js +529 -0
- package/dist/runtime/heapEffect.js.map +1 -0
- package/dist/runtime/heapEffectIR.d.ts +34 -0
- package/dist/runtime/heapEffectIR.d.ts.map +1 -0
- package/dist/runtime/heapEffectIR.js +1161 -0
- package/dist/runtime/heapEffectIR.js.map +1 -0
- package/dist/runtime/heapEligibility.d.ts +9 -0
- package/dist/runtime/heapEligibility.d.ts.map +1 -0
- package/dist/runtime/heapEligibility.js +195 -0
- package/dist/runtime/heapEligibility.js.map +1 -0
- package/dist/runtime/heapScene.d.ts +240 -31
- package/dist/runtime/heapScene.d.ts.map +1 -1
- package/dist/runtime/heapScene.js +3334 -265
- package/dist/runtime/heapScene.js.map +1 -1
- package/dist/runtime/heapShaderFamily.d.ts +132 -0
- package/dist/runtime/heapShaderFamily.d.ts.map +1 -0
- package/dist/runtime/heapShaderFamily.js +866 -0
- package/dist/runtime/heapShaderFamily.js.map +1 -0
- package/dist/runtime/hybridScene.d.ts +133 -0
- package/dist/runtime/hybridScene.d.ts.map +1 -0
- package/dist/runtime/hybridScene.js +159 -0
- package/dist/runtime/hybridScene.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +9 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/renderTask.d.ts +21 -4
- package/dist/runtime/renderTask.d.ts.map +1 -1
- package/dist/runtime/renderTask.js +127 -32
- package/dist/runtime/renderTask.js.map +1 -1
- package/dist/runtime/runtime.d.ts +33 -3
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +12 -3
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/scenePass.d.ts +28 -3
- package/dist/runtime/scenePass.d.ts.map +1 -1
- package/dist/runtime/scenePass.js +37 -4
- package/dist/runtime/scenePass.js.map +1 -1
- package/dist/runtime/textureAtlas/atlasMipGutterKernel.d.ts +35 -0
- package/dist/runtime/textureAtlas/atlasMipGutterKernel.d.ts.map +1 -0
- package/dist/runtime/textureAtlas/atlasMipGutterKernel.js +247 -0
- package/dist/runtime/textureAtlas/atlasMipGutterKernel.js.map +1 -0
- package/dist/runtime/textureAtlas/atlasPool.d.ts +240 -0
- package/dist/runtime/textureAtlas/atlasPool.d.ts.map +1 -0
- package/dist/runtime/textureAtlas/atlasPool.js +798 -0
- package/dist/runtime/textureAtlas/atlasPool.js.map +1 -0
- package/dist/runtime/textureAtlas/bvhTree2d.d.ts +33 -0
- package/dist/runtime/textureAtlas/bvhTree2d.d.ts.map +1 -0
- package/dist/runtime/textureAtlas/bvhTree2d.js +501 -0
- package/dist/runtime/textureAtlas/bvhTree2d.js.map +1 -0
- package/dist/runtime/textureAtlas/packer.d.ts +50 -0
- package/dist/runtime/textureAtlas/packer.d.ts.map +1 -0
- package/dist/runtime/textureAtlas/packer.js +390 -0
- package/dist/runtime/textureAtlas/packer.js.map +1 -0
- package/dist/window/loop.d.ts +14 -0
- package/dist/window/loop.d.ts.map +1 -1
- package/dist/window/loop.js +18 -5
- package/dist/window/loop.js.map +1 -1
- package/package.json +6 -5
- package/src/core/command.ts +9 -9
- package/src/core/renderTask.ts +55 -2
- package/src/resources/preparedRenderObject.ts +3 -3
- package/src/resources/uniformBuffer.ts +15 -0
- package/src/runtime/derivedUniforms/dispatch.ts +407 -0
- package/src/runtime/derivedUniforms/index.ts +52 -0
- package/src/runtime/derivedUniforms/recipes.ts +159 -0
- package/src/runtime/derivedUniforms/sceneIntegration.ts +239 -0
- package/src/runtime/derivedUniforms/slotId.ts +35 -0
- package/src/runtime/derivedUniforms/slots.ts +155 -0
- package/src/runtime/derivedUniforms/uberKernel.wgsl.ts +220 -0
- package/src/runtime/flattenTree.ts +46 -0
- package/src/runtime/heapAdapter.ts +314 -0
- package/src/runtime/heapEffect.ts +728 -0
- package/src/runtime/heapEffectIR.ts +1211 -0
- package/src/runtime/heapEligibility.ts +189 -0
- package/src/runtime/heapScene.ts +3981 -349
- package/src/runtime/heapShaderFamily.ts +1102 -0
- package/src/runtime/hybridScene.ts +310 -0
- package/src/runtime/index.ts +45 -1
- package/src/runtime/renderTask.ts +167 -32
- package/src/runtime/runtime.ts +37 -4
- package/src/runtime/scenePass.ts +39 -4
- package/src/runtime/textureAtlas/atlasMipGutterKernel.ts +291 -0
- package/src/runtime/textureAtlas/atlasPool.ts +991 -0
- package/src/runtime/textureAtlas/bvhTree2d.ts +530 -0
- package/src/runtime/textureAtlas/packer.ts +429 -0
- package/src/window/loop.ts +32 -6
- package/dist/runtime/heapShader.d.ts +0 -12
- package/dist/runtime/heapShader.d.ts.map +0 -1
- package/dist/runtime/heapShader.js +0 -157
- package/dist/runtime/heapShader.js.map +0 -1
- package/src/runtime/heapShader.ts +0 -185
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { aval, IAdaptiveObject } from "@aardworx/wombat.adaptive";
|
|
2
|
+
import type { Trafo3d } from "@aardworx/wombat.base";
|
|
3
|
+
import { ConstituentSlots, type SlotIndex } from "./slots.js";
|
|
4
|
+
import { RecipeId } from "./recipes.js";
|
|
5
|
+
import { DerivedUniformsDispatcher, DerivedUniformsPipeline } from "./dispatch.js";
|
|
6
|
+
/** Scene-wide §7 state. One per heap scene. Owns the single records
|
|
7
|
+
* buffer + dispatcher — all buckets share constituents, dirty mask,
|
|
8
|
+
* AND main heap (arena.attrs.buffer), so per-bucket records would
|
|
9
|
+
* just multiply dispatch overhead for no reason. */
|
|
10
|
+
export declare class DerivedUniformsScene {
|
|
11
|
+
readonly device: GPUDevice;
|
|
12
|
+
readonly constituents: ConstituentSlots;
|
|
13
|
+
readonly pipeline: DerivedUniformsPipeline;
|
|
14
|
+
readonly dispatcher: DerivedUniformsDispatcher;
|
|
15
|
+
/** Constituents storage GPU buffer (df32 mat4 array). */
|
|
16
|
+
constituentsBuf: GPUBuffer;
|
|
17
|
+
/** Caller-owned main heap (arena.attrs.buffer). Updated via
|
|
18
|
+
* `rebindMainHeap` on arena resize. */
|
|
19
|
+
private mainHeapRef;
|
|
20
|
+
/** Bumped each time a shared GPU buffer is replaced. */
|
|
21
|
+
bufferEpoch: number;
|
|
22
|
+
constructor(device: GPUDevice, mainHeapBuf: GPUBuffer, opts?: {
|
|
23
|
+
initialConstituentSlots?: number;
|
|
24
|
+
initialRecordCapacity?: number;
|
|
25
|
+
});
|
|
26
|
+
rebindMainHeap(mainHeapBuf: GPUBuffer): void;
|
|
27
|
+
ensureConstituentsCapacity(requiredBytes: number): void;
|
|
28
|
+
/** Routed from heap scene's `inputChanged(t, o)`. Returns true iff
|
|
29
|
+
* `o` matched a known constituent aval. */
|
|
30
|
+
routeInputChanged(o: IAdaptiveObject): boolean;
|
|
31
|
+
/** Apply the dirty set: upload changed constituent values. O(changed). */
|
|
32
|
+
uploadDirty(dirty: ReadonlySet<SlotIndex>): void;
|
|
33
|
+
dispose(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface RoTrafoInputs {
|
|
36
|
+
readonly modelTrafo?: aval<Trafo3d> | undefined;
|
|
37
|
+
readonly viewTrafo?: aval<Trafo3d> | undefined;
|
|
38
|
+
readonly projTrafo?: aval<Trafo3d> | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface RoDerivedRequest {
|
|
41
|
+
readonly trafos: RoTrafoInputs;
|
|
42
|
+
readonly requiredNames: readonly string[];
|
|
43
|
+
readonly byteOffsetByName: ReadonlyMap<string, number>;
|
|
44
|
+
readonly drawHeaderBaseByte: number;
|
|
45
|
+
}
|
|
46
|
+
export interface RoRegistration {
|
|
47
|
+
/** Per-record handles (RecordsBuffer ids) — passed back to deregister. */
|
|
48
|
+
readonly recordIds: readonly number[];
|
|
49
|
+
readonly constituentAvals: readonly aval<Trafo3d>[];
|
|
50
|
+
}
|
|
51
|
+
/** Register all derived-uniform records for one RO. */
|
|
52
|
+
export declare function registerRoDerivations(scene: DerivedUniformsScene, req: RoDerivedRequest): RoRegistration;
|
|
53
|
+
export declare function deregisterRoDerivations(scene: DerivedUniformsScene, reg: RoRegistration): void;
|
|
54
|
+
export declare function isDerivedUniformName(name: string): boolean;
|
|
55
|
+
export { RecipeId };
|
|
56
|
+
//# sourceMappingURL=sceneIntegration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sceneIntegration.d.ts","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/sceneIntegration.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAEyB,KAAK,SAAS,EAExD,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,QAAQ,EAGT,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EAAE,uBAAuB,EAEnD,MAAM,eAAe,CAAC;AAEvB;;;qDAGqD;AACrD,qBAAa,oBAAoB;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAM,uBAAuB,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAI,yBAAyB,CAAC;IACjD,yDAAyD;IACzD,eAAe,EAAE,SAAS,CAAC;IAC3B;4CACwC;IACxC,OAAO,CAAC,WAAW,CAAyB;IAC5C,wDAAwD;IACxD,WAAW,SAAK;gBAGd,MAAM,EAAO,SAAS,EACtB,WAAW,EAAE,SAAS,EACtB,IAAI,CAAC,EAAQ;QAAE,uBAAuB,CAAC,EAAE,MAAM,CAAC;QAAC,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAAE;IAwBnF,cAAc,CAAC,WAAW,EAAE,SAAS,GAAG,IAAI;IAI5C,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IA0BvD;gDAC4C;IAC5C,iBAAiB,CAAC,CAAC,EAAE,eAAe,GAAG,OAAO;IAM9C,0EAA0E;IAC1E,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI;IAQhD,OAAO,IAAI,IAAI;CAIhB;AAID,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAY,aAAa,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAK,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CACrD;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,CACnC,KAAK,EAAG,oBAAoB,EAC5B,GAAG,EAAK,gBAAgB,GACvB,cAAc,CA8DhB;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,GAAG,EAAI,cAAc,GACpB,IAAI,CAGN;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// §7 → heap scene integration helper.
|
|
2
|
+
//
|
|
3
|
+
// Subscription model. Standard adaptive idiom: calling `av.getValue(t)`
|
|
4
|
+
// inside an `evaluateAlways(t, ...)` scope (re-)adds the evaluating
|
|
5
|
+
// object to `av.outputs`. We don't manage subscription manually.
|
|
6
|
+
//
|
|
7
|
+
// Per frame, the heap scene's `update()` runs `evaluateAlways` once on
|
|
8
|
+
// the parent scene-object (as it already does). Inside that scope:
|
|
9
|
+
// 1. `scene.constituents.pullDirty(token)` drains the dirty queue.
|
|
10
|
+
// For each dirty aval, it calls `getValue(token)` — which both
|
|
11
|
+
// gives us the new value AND re-establishes our subscription on
|
|
12
|
+
// that specific aval. O(changed). Avals that didn't change keep
|
|
13
|
+
// us in their outputs from earlier evaluations.
|
|
14
|
+
// 2. `scene.uploadDirty(dirtySlots)` — O(changed) value uploads +
|
|
15
|
+
// O(changed) bitmask flips.
|
|
16
|
+
// 3. Per bucket: `bucket.dispatcher.encode(enc)`. The kernel
|
|
17
|
+
// early-returns on records whose inputs are all clean.
|
|
18
|
+
//
|
|
19
|
+
// On clean frames pullDirty/uploadDirty are no-ops. The records
|
|
20
|
+
// buffer is static. CPU steady-state cost: zero.
|
|
21
|
+
import { ConstituentSlots, DF32_MAT4_BYTES, } from "./slots.js";
|
|
22
|
+
import { RecipeId, recipeIdByName, recipeInputs, recipeInputCount, DERIVED_UNIFORM_NAMES, } from "./recipes.js";
|
|
23
|
+
import { DerivedUniformsDispatcher, DerivedUniformsPipeline, uploadConstituentsRange, } from "./dispatch.js";
|
|
24
|
+
/** Scene-wide §7 state. One per heap scene. Owns the single records
|
|
25
|
+
* buffer + dispatcher — all buckets share constituents, dirty mask,
|
|
26
|
+
* AND main heap (arena.attrs.buffer), so per-bucket records would
|
|
27
|
+
* just multiply dispatch overhead for no reason. */
|
|
28
|
+
export class DerivedUniformsScene {
|
|
29
|
+
device;
|
|
30
|
+
constituents;
|
|
31
|
+
pipeline;
|
|
32
|
+
dispatcher;
|
|
33
|
+
/** Constituents storage GPU buffer (df32 mat4 array). */
|
|
34
|
+
constituentsBuf;
|
|
35
|
+
/** Caller-owned main heap (arena.attrs.buffer). Updated via
|
|
36
|
+
* `rebindMainHeap` on arena resize. */
|
|
37
|
+
mainHeapRef;
|
|
38
|
+
/** Bumped each time a shared GPU buffer is replaced. */
|
|
39
|
+
bufferEpoch = 0;
|
|
40
|
+
constructor(device, mainHeapBuf, opts) {
|
|
41
|
+
this.device = device;
|
|
42
|
+
const initial = opts?.initialConstituentSlots ?? 64;
|
|
43
|
+
const subscribe = () => { };
|
|
44
|
+
this.constituents = new ConstituentSlots(subscribe, initial);
|
|
45
|
+
this.pipeline = new DerivedUniformsPipeline(device);
|
|
46
|
+
this.constituentsBuf = device.createBuffer({
|
|
47
|
+
label: "derivedUniforms.constituents",
|
|
48
|
+
size: initial * DF32_MAT4_BYTES,
|
|
49
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
50
|
+
});
|
|
51
|
+
this.mainHeapRef = { current: mainHeapBuf };
|
|
52
|
+
this.dispatcher = new DerivedUniformsDispatcher(device, this.pipeline, {
|
|
53
|
+
constituentsBuf: () => this.constituentsBuf,
|
|
54
|
+
mainHeapBuf: () => this.mainHeapRef.current,
|
|
55
|
+
}, opts?.initialRecordCapacity ?? 64);
|
|
56
|
+
}
|
|
57
|
+
rebindMainHeap(mainHeapBuf) {
|
|
58
|
+
this.mainHeapRef.current = mainHeapBuf;
|
|
59
|
+
}
|
|
60
|
+
ensureConstituentsCapacity(requiredBytes) {
|
|
61
|
+
if (requiredBytes <= this.constituentsBuf.size)
|
|
62
|
+
return;
|
|
63
|
+
let cap = this.constituentsBuf.size;
|
|
64
|
+
while (cap < requiredBytes)
|
|
65
|
+
cap *= 2;
|
|
66
|
+
this.constituentsBuf.destroy();
|
|
67
|
+
this.constituentsBuf = this.device.createBuffer({
|
|
68
|
+
label: "derivedUniforms.constituents",
|
|
69
|
+
size: cap,
|
|
70
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
|
71
|
+
});
|
|
72
|
+
this.bufferEpoch++;
|
|
73
|
+
// The fresh buffer is zero-initialized; the previous contents are
|
|
74
|
+
// gone. Re-upload everything we've ever packed (slot 0..slotCount).
|
|
75
|
+
// Without this, slots that were last written before the grow read
|
|
76
|
+
// zero on the GPU — every df_mul on them produces NaN.
|
|
77
|
+
const slotCount = this.constituents.slotCount;
|
|
78
|
+
if (slotCount > 0) {
|
|
79
|
+
const mirror = this.constituents.cpuMirror;
|
|
80
|
+
this.device.queue.writeBuffer(this.constituentsBuf, 0, mirror.buffer, mirror.byteOffset, slotCount * DF32_MAT4_BYTES);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Routed from heap scene's `inputChanged(t, o)`. Returns true iff
|
|
84
|
+
* `o` matched a known constituent aval. */
|
|
85
|
+
routeInputChanged(o) {
|
|
86
|
+
if (!this.constituents.has(o))
|
|
87
|
+
return false;
|
|
88
|
+
this.constituents.markDirty(o);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
/** Apply the dirty set: upload changed constituent values. O(changed). */
|
|
92
|
+
uploadDirty(dirty) {
|
|
93
|
+
if (dirty.size === 0)
|
|
94
|
+
return;
|
|
95
|
+
this.ensureConstituentsCapacity(this.constituents.slotCount * DF32_MAT4_BYTES);
|
|
96
|
+
uploadConstituentsRange(this.device, this.constituentsBuf, this.constituents.cpuMirror, dirty);
|
|
97
|
+
}
|
|
98
|
+
dispose() {
|
|
99
|
+
this.dispatcher.dispose();
|
|
100
|
+
this.constituentsBuf.destroy();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Register all derived-uniform records for one RO. */
|
|
104
|
+
export function registerRoDerivations(scene, req) {
|
|
105
|
+
if (req.requiredNames.length === 0) {
|
|
106
|
+
return { recordIds: [], constituentAvals: [] };
|
|
107
|
+
}
|
|
108
|
+
const acquiredAvals = [];
|
|
109
|
+
const pairFor = new Map();
|
|
110
|
+
const TRAFO_FIELD = {
|
|
111
|
+
Model: "modelTrafo", View: "viewTrafo", Proj: "projTrafo",
|
|
112
|
+
};
|
|
113
|
+
const acquirePair = (key) => {
|
|
114
|
+
let p = pairFor.get(key);
|
|
115
|
+
if (p !== undefined)
|
|
116
|
+
return p;
|
|
117
|
+
const av = req.trafos[TRAFO_FIELD[key]];
|
|
118
|
+
if (av === undefined) {
|
|
119
|
+
throw new Error(`derivedUniforms: RO requires '${key}' trafo but trafos.${TRAFO_FIELD[key]} is undefined`);
|
|
120
|
+
}
|
|
121
|
+
p = scene.constituents.acquire(av);
|
|
122
|
+
pairFor.set(key, p);
|
|
123
|
+
acquiredAvals.push(av);
|
|
124
|
+
return p;
|
|
125
|
+
};
|
|
126
|
+
const resolveConstituent = (ref) => {
|
|
127
|
+
switch (ref) {
|
|
128
|
+
case "Model.fwd": return acquirePair("Model").fwd;
|
|
129
|
+
case "Model.bwd": return acquirePair("Model").inv;
|
|
130
|
+
case "View.fwd": return acquirePair("View").fwd;
|
|
131
|
+
case "View.bwd": return acquirePair("View").inv;
|
|
132
|
+
case "Proj.fwd": return acquirePair("Proj").fwd;
|
|
133
|
+
case "Proj.bwd": return acquirePair("Proj").inv;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const recordIds = [];
|
|
137
|
+
for (const name of req.requiredNames) {
|
|
138
|
+
const id = recipeIdByName(name);
|
|
139
|
+
if (id === undefined) {
|
|
140
|
+
throw new Error(`derivedUniforms: unknown derived name '${name}'`);
|
|
141
|
+
}
|
|
142
|
+
const off = req.byteOffsetByName.get(name);
|
|
143
|
+
if (off === undefined) {
|
|
144
|
+
throw new Error(`derivedUniforms: '${name}' has no byte offset in drawHeader for this RO`);
|
|
145
|
+
}
|
|
146
|
+
const refs = recipeInputs(id);
|
|
147
|
+
const slots = refs.map(resolveConstituent);
|
|
148
|
+
const inCount = recipeInputCount(id);
|
|
149
|
+
const rec = {
|
|
150
|
+
recipe: id,
|
|
151
|
+
in0: slots[0],
|
|
152
|
+
in1: inCount >= 2 ? slots[1] : 0,
|
|
153
|
+
in2: inCount >= 3 ? slots[2] : 0,
|
|
154
|
+
outByte: req.drawHeaderBaseByte + off,
|
|
155
|
+
};
|
|
156
|
+
recordIds.push(scene.dispatcher.records.add(rec));
|
|
157
|
+
}
|
|
158
|
+
return { recordIds, constituentAvals: acquiredAvals };
|
|
159
|
+
}
|
|
160
|
+
export function deregisterRoDerivations(scene, reg) {
|
|
161
|
+
for (const id of reg.recordIds)
|
|
162
|
+
scene.dispatcher.records.remove(id);
|
|
163
|
+
for (const av of reg.constituentAvals)
|
|
164
|
+
scene.constituents.release(av);
|
|
165
|
+
}
|
|
166
|
+
export function isDerivedUniformName(name) {
|
|
167
|
+
return DERIVED_UNIFORM_NAMES.has(name);
|
|
168
|
+
}
|
|
169
|
+
// Re-export RecipeId for callers (e.g. heapScene's drawHeader walk).
|
|
170
|
+
export { RecipeId };
|
|
171
|
+
//# sourceMappingURL=sceneIntegration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sceneIntegration.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/sceneIntegration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Branded u32 — top bit selects heap, low 31 bits are slot index. */
|
|
2
|
+
export type SlotId = number & {
|
|
3
|
+
readonly __slotId: unique symbol;
|
|
4
|
+
};
|
|
5
|
+
export declare const SlotId: {
|
|
6
|
+
/** Encode a Constituents-heap slot. */
|
|
7
|
+
constituent(idx: number): SlotId;
|
|
8
|
+
/** Encode an Intermediates-heap slot. */
|
|
9
|
+
intermediate(idx: number): SlotId;
|
|
10
|
+
isIntermediate(s: SlotId): boolean;
|
|
11
|
+
index(s: SlotId): number;
|
|
12
|
+
};
|
|
13
|
+
/** Bytes per df32 mat4 slot: 16 entries × 2 floats × 4 bytes. */
|
|
14
|
+
export declare const DF32_MAT4_BYTES = 128;
|
|
15
|
+
//# sourceMappingURL=slotId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slotId.d.ts","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/slotId.ts"],"names":[],"mappings":"AAWA,sEAAsE;AACtE,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAInE,eAAO,MAAM,MAAM;IACjB,uCAAuC;qBACtB,MAAM,GAAG,MAAM;IAGhC,yCAAyC;sBACvB,MAAM,GAAG,MAAM;sBAGf,MAAM,GAAG,OAAO;aAGzB,MAAM,GAAG,MAAM;CAGzB,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Slot-ID encoding for the §7 uber kernel.
|
|
2
|
+
//
|
|
3
|
+
// One u32 namespace covers both the Constituents heap (df32 trafos
|
|
4
|
+
// uploaded from CPU) and the Intermediates heap (df32 outputs of
|
|
5
|
+
// layer-1 recipes). The high bit selects the heap; the low 31 bits are
|
|
6
|
+
// the linear index within that heap. Each slot holds one mat4 in df32
|
|
7
|
+
// = 16 vec2<f32> = 128 bytes.
|
|
8
|
+
//
|
|
9
|
+
// Uber-kernel side: a single helper reads from either heap based on
|
|
10
|
+
// the flag — see `read_mat4_df` in the WGSL source.
|
|
11
|
+
const FLAG_INTERMEDIATE = 0x80000000;
|
|
12
|
+
export const SlotId = {
|
|
13
|
+
/** Encode a Constituents-heap slot. */
|
|
14
|
+
constituent(idx) {
|
|
15
|
+
return (idx & 0x7FFFFFFF);
|
|
16
|
+
},
|
|
17
|
+
/** Encode an Intermediates-heap slot. */
|
|
18
|
+
intermediate(idx) {
|
|
19
|
+
return ((idx & 0x7FFFFFFF) | FLAG_INTERMEDIATE) >>> 0;
|
|
20
|
+
},
|
|
21
|
+
isIntermediate(s) {
|
|
22
|
+
return (s & FLAG_INTERMEDIATE) !== 0;
|
|
23
|
+
},
|
|
24
|
+
index(s) {
|
|
25
|
+
return s & 0x7FFFFFFF;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/** Bytes per df32 mat4 slot: 16 entries × 2 floats × 4 bytes. */
|
|
29
|
+
export const DF32_MAT4_BYTES = 128;
|
|
30
|
+
//# sourceMappingURL=slotId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slotId.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/slotId.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,mEAAmE;AACnE,iEAAiE;AACjE,uEAAuE;AACvE,sEAAsE;AACtE,8BAA8B;AAC9B,EAAE;AACF,oEAAoE;AACpE,oDAAoD;AAKpD,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAErC,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,uCAAuC;IACvC,WAAW,CAAC,GAAW;QACrB,OAAO,CAAC,GAAG,GAAG,UAAU,CAAW,CAAC;IACtC,CAAC;IACD,yCAAyC;IACzC,YAAY,CAAC,GAAW;QACtB,OAAO,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAW,CAAC;IAClE,CAAC;IACD,cAAc,CAAC,CAAS;QACtB,OAAO,CAAC,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IACD,KAAK,CAAC,CAAS;QACb,OAAO,CAAC,GAAG,UAAU,CAAC;IACxB,CAAC;CACF,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { aval, AdaptiveToken, IAdaptiveObject } from "@aardworx/wombat.adaptive";
|
|
2
|
+
import type { Trafo3d } from "@aardworx/wombat.base";
|
|
3
|
+
/** Slot index — pure linear index into the constituents heap. */
|
|
4
|
+
export type SlotIndex = number & {
|
|
5
|
+
readonly __slotIndex: unique symbol;
|
|
6
|
+
};
|
|
7
|
+
/** Bytes per df32 mat4 slot: 16 entries × 2 floats × 4 bytes. */
|
|
8
|
+
export declare const DF32_MAT4_BYTES = 128;
|
|
9
|
+
/** Forward + inverse slot indices for one Trafo3d aval. */
|
|
10
|
+
export interface PairedSlots {
|
|
11
|
+
readonly fwd: SlotIndex;
|
|
12
|
+
readonly inv: SlotIndex;
|
|
13
|
+
}
|
|
14
|
+
/** Caller-provided hook: register the parent scene-object as a
|
|
15
|
+
* downstream output of `av`. Without this, the framework never
|
|
16
|
+
* delivers `inputChanged` and our dirty queue stays empty. */
|
|
17
|
+
export type SubscribeFn = (av: aval<unknown>) => void;
|
|
18
|
+
/** A single derivation request: "run this recipe over these constituent
|
|
19
|
+
* slots, write its output to `out_byte` in main heap." Identity-tracked
|
|
20
|
+
* so add/remove can locate the row in the records buffer. */
|
|
21
|
+
export interface DerivationRecord {
|
|
22
|
+
readonly recipe: number;
|
|
23
|
+
readonly in0: SlotIndex;
|
|
24
|
+
readonly in1: SlotIndex;
|
|
25
|
+
readonly in2: SlotIndex;
|
|
26
|
+
readonly outByte: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class ConstituentSlots {
|
|
29
|
+
private readonly pool;
|
|
30
|
+
private readonly byAval;
|
|
31
|
+
private readonly dirtyAvals;
|
|
32
|
+
private mirror;
|
|
33
|
+
private readonly subscribe;
|
|
34
|
+
constructor(subscribe: SubscribeFn, initialCapacity?: number);
|
|
35
|
+
acquire(av: aval<Trafo3d>): PairedSlots;
|
|
36
|
+
release(av: aval<Trafo3d>): void;
|
|
37
|
+
has(o: IAdaptiveObject): boolean;
|
|
38
|
+
markDirty(o: IAdaptiveObject): void;
|
|
39
|
+
/** Drain the dirty queue: pack each marked aval's value into the
|
|
40
|
+
* mirror, return the affected slot indices. O(changed). The
|
|
41
|
+
* returned Set is OWNED by ConstituentSlots and reused frame to
|
|
42
|
+
* frame — callers must not retain it past the current frame. */
|
|
43
|
+
pullDirty(token: AdaptiveToken): Set<SlotIndex>;
|
|
44
|
+
private readonly dirtyOut;
|
|
45
|
+
get cpuMirror(): Float32Array;
|
|
46
|
+
get slotCount(): number;
|
|
47
|
+
private ensureCapacity;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/slots.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,KAAK,EAAQ,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE3D,iEAAiE;AACjE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAEzE,iEAAiE;AACjE,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;CACzB;AAED;;+DAE+D;AAC/D,MAAM,MAAM,WAAW,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AAEtD;;8DAE8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAM,SAAS,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAM,SAAS,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAM,SAAS,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAiCD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8C;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,SAAS,EAAE,WAAW,EAAE,eAAe,SAAK;IAKxD,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,WAAW;IAevC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;IAchC,GAAG,CAAC,CAAC,EAAE,eAAe,GAAG,OAAO;IAGhC,SAAS,CAAC,CAAC,EAAE,eAAe,GAAG,IAAI;IAKnC;;;qEAGiE;IACjE,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC;IAc/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IAEjD,IAAI,SAAS,IAAI,YAAY,CAAwB;IACrD,IAAI,SAAS,IAAI,MAAM,CAAoC;IAE3D,OAAO,CAAC,cAAc;CASvB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// §7 constituent slot allocator + derivation record store.
|
|
2
|
+
//
|
|
3
|
+
// One refcounted heap of df32 mat4 slots, keyed by `aval<Trafo3d>`.
|
|
4
|
+
// Each acquired aval gets an adjacent (fwd, inv) slot pair on the
|
|
5
|
+
// constituents heap. The pull phase reads each tracked aval through
|
|
6
|
+
// `getValue(token)` and re-packs the slot pair only if the returned
|
|
7
|
+
// Trafo3d differs from the previously cached value (reference identity
|
|
8
|
+
// — Trafo3d is immutable).
|
|
9
|
+
//
|
|
10
|
+
// Lifetime is RO-driven: addDraw → acquire(...), removeDraw → release.
|
|
11
|
+
/** Bytes per df32 mat4 slot: 16 entries × 2 floats × 4 bytes. */
|
|
12
|
+
export const DF32_MAT4_BYTES = 128;
|
|
13
|
+
class IndexPool {
|
|
14
|
+
next = 0;
|
|
15
|
+
free = [];
|
|
16
|
+
alloc() { return this.free.pop() ?? this.next++; }
|
|
17
|
+
release(idx) { this.free.push(idx); }
|
|
18
|
+
get highWaterMark() { return this.next; }
|
|
19
|
+
}
|
|
20
|
+
function packEntry(mirror, off, v) {
|
|
21
|
+
const hi = Math.fround(v);
|
|
22
|
+
mirror[off] = hi;
|
|
23
|
+
mirror[off + 1] = Math.fround(v - hi);
|
|
24
|
+
}
|
|
25
|
+
function packMat4ToSlot(mirror, slotIdx, m) {
|
|
26
|
+
const base = slotIdx * 32;
|
|
27
|
+
packEntry(mirror, base + 0, m.M00);
|
|
28
|
+
packEntry(mirror, base + 2, m.M01);
|
|
29
|
+
packEntry(mirror, base + 4, m.M02);
|
|
30
|
+
packEntry(mirror, base + 6, m.M03);
|
|
31
|
+
packEntry(mirror, base + 8, m.M10);
|
|
32
|
+
packEntry(mirror, base + 10, m.M11);
|
|
33
|
+
packEntry(mirror, base + 12, m.M12);
|
|
34
|
+
packEntry(mirror, base + 14, m.M13);
|
|
35
|
+
packEntry(mirror, base + 16, m.M20);
|
|
36
|
+
packEntry(mirror, base + 18, m.M21);
|
|
37
|
+
packEntry(mirror, base + 20, m.M22);
|
|
38
|
+
packEntry(mirror, base + 22, m.M23);
|
|
39
|
+
packEntry(mirror, base + 24, m.M30);
|
|
40
|
+
packEntry(mirror, base + 26, m.M31);
|
|
41
|
+
packEntry(mirror, base + 28, m.M32);
|
|
42
|
+
packEntry(mirror, base + 30, m.M33);
|
|
43
|
+
}
|
|
44
|
+
export class ConstituentSlots {
|
|
45
|
+
pool = new IndexPool();
|
|
46
|
+
byAval = new Map();
|
|
47
|
+
dirtyAvals = new Set();
|
|
48
|
+
mirror;
|
|
49
|
+
subscribe;
|
|
50
|
+
constructor(subscribe, initialCapacity = 64) {
|
|
51
|
+
this.subscribe = subscribe;
|
|
52
|
+
this.mirror = new Float32Array(initialCapacity * 32);
|
|
53
|
+
}
|
|
54
|
+
acquire(av) {
|
|
55
|
+
let entry = this.byAval.get(av);
|
|
56
|
+
if (entry === undefined) {
|
|
57
|
+
const fwd = this.pool.alloc();
|
|
58
|
+
const inv = this.pool.alloc();
|
|
59
|
+
entry = { slots: { fwd, inv }, refs: 0 };
|
|
60
|
+
this.byAval.set(av, entry);
|
|
61
|
+
this.ensureCapacity(this.pool.highWaterMark);
|
|
62
|
+
this.subscribe(av);
|
|
63
|
+
this.dirtyAvals.add(av);
|
|
64
|
+
}
|
|
65
|
+
entry.refs++;
|
|
66
|
+
return entry.slots;
|
|
67
|
+
}
|
|
68
|
+
release(av) {
|
|
69
|
+
const entry = this.byAval.get(av);
|
|
70
|
+
if (entry === undefined) {
|
|
71
|
+
throw new Error("ConstituentSlots.release: aval was never acquired");
|
|
72
|
+
}
|
|
73
|
+
entry.refs--;
|
|
74
|
+
if (entry.refs === 0) {
|
|
75
|
+
this.pool.release(entry.slots.fwd);
|
|
76
|
+
this.pool.release(entry.slots.inv);
|
|
77
|
+
this.byAval.delete(av);
|
|
78
|
+
this.dirtyAvals.delete(av);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
has(o) {
|
|
82
|
+
return this.byAval.has(o);
|
|
83
|
+
}
|
|
84
|
+
markDirty(o) {
|
|
85
|
+
const av = o;
|
|
86
|
+
if (this.byAval.has(av))
|
|
87
|
+
this.dirtyAvals.add(av);
|
|
88
|
+
}
|
|
89
|
+
/** Drain the dirty queue: pack each marked aval's value into the
|
|
90
|
+
* mirror, return the affected slot indices. O(changed). The
|
|
91
|
+
* returned Set is OWNED by ConstituentSlots and reused frame to
|
|
92
|
+
* frame — callers must not retain it past the current frame. */
|
|
93
|
+
pullDirty(token) {
|
|
94
|
+
this.dirtyOut.clear();
|
|
95
|
+
for (const av of this.dirtyAvals) {
|
|
96
|
+
const entry = this.byAval.get(av);
|
|
97
|
+
if (entry === undefined)
|
|
98
|
+
continue;
|
|
99
|
+
const value = av.getValue(token);
|
|
100
|
+
packMat4ToSlot(this.mirror, entry.slots.fwd, value.forward);
|
|
101
|
+
packMat4ToSlot(this.mirror, entry.slots.inv, value.backward);
|
|
102
|
+
this.dirtyOut.add(entry.slots.fwd);
|
|
103
|
+
this.dirtyOut.add(entry.slots.inv);
|
|
104
|
+
}
|
|
105
|
+
this.dirtyAvals.clear();
|
|
106
|
+
return this.dirtyOut;
|
|
107
|
+
}
|
|
108
|
+
dirtyOut = new Set();
|
|
109
|
+
get cpuMirror() { return this.mirror; }
|
|
110
|
+
get slotCount() { return this.pool.highWaterMark; }
|
|
111
|
+
ensureCapacity(slots) {
|
|
112
|
+
const need = slots * 32;
|
|
113
|
+
if (need <= this.mirror.length)
|
|
114
|
+
return;
|
|
115
|
+
let cap = this.mirror.length;
|
|
116
|
+
while (cap < need)
|
|
117
|
+
cap *= 2;
|
|
118
|
+
const grown = new Float32Array(cap);
|
|
119
|
+
grown.set(this.mirror);
|
|
120
|
+
this.mirror = grown;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=slots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/slots.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const DERIVED_UBER_KERNEL_WGSL = "\n\n// \u2500\u2500\u2500 Bindings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n@group(0) @binding(0) var<storage, read> Constituents: array<vec2<f32>>;\n@group(0) @binding(1) var<storage, read_write> MainHeap: array<f32>;\n\nstruct Record {\n recipe_id: u32,\n in0: u32, // constituent slot index\n in1: u32, // constituent slot index, 0 if unused\n in2: u32, // constituent slot index, 0 if unused\n out_byte: u32, // byte offset in MainHeap\n _pad: u32, // bumps stride to 24 (defensively 16-aligned)\n}\n@group(0) @binding(2) var<storage, read> Records: array<Record>;\n\n// Live record count. arrayLength(Records) reports the GPU buffer's\n// capacity (rounded up by allocator growth), not the live count \u2014\n// trailing slots hold stale data from swap-removed records. Threads\n// past Count.count would read stale records and trample random\n// MainHeap bytes.\nstruct CountUniform { count: u32 }\n@group(0) @binding(3) var<uniform> Count: CountUniform;\n\n// \u2500\u2500\u2500 df32 primitives \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfn split12(a: f32) -> vec2<f32> {\n let hi = bitcast<f32>(bitcast<u32>(a) & 0xFFFFE000u);\n let lo = a - hi;\n return vec2<f32>(hi, lo);\n}\n\nfn two_sum(a: f32, b: f32) -> vec2<f32> {\n let s = a + b;\n let bb = fma(1.0, s, -a);\n let t1 = fma(1.0, s, -bb);\n let t2 = fma(1.0, a, -t1);\n let t3 = fma(1.0, b, -bb);\n return vec2<f32>(s, t2 + t3);\n}\n\nfn quick_two_sum(a: f32, b: f32) -> vec2<f32> {\n let s = a + b;\n let t = fma(1.0, s, -a);\n return vec2<f32>(s, fma(1.0, b, -t));\n}\n\nfn two_prod(a: f32, b: f32) -> vec2<f32> {\n let p = a * b;\n let A = split12(a);\n let B = split12(b);\n let err = ((A.x * B.x - p) + A.x * B.y + A.y * B.x) + A.y * B.y;\n return vec2<f32>(p, err);\n}\n\nfn df_add(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {\n let s = two_sum(a.x, b.x);\n let t = two_sum(a.y, b.y);\n let s3 = quick_two_sum(s.x, s.y + t.x);\n return quick_two_sum(s3.x, s3.y + t.y);\n}\n\nfn df_mul(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {\n let p = two_prod(a.x, b.x);\n let cross1 = fma(a.x, b.y, p.y);\n let cross = fma(a.y, b.x, cross1);\n return quick_two_sum(p.x, cross);\n}\n\n// \u2500\u2500\u2500 Constituents access \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// One slot = 16 vec2<f32> = one df32 mat4 in row-major order\n// (matching Aardvark M44d convention). Element (row, col) of slot k\n// lives at vec2 index k*16 + row*4 + col.\n\nfn read_entry(slot: u32, row: u32, col: u32) -> vec2<f32> {\n return Constituents[slot * 16u + row * 4u + col];\n}\n\n// (A \u00B7 B) entry (r, c) in df32, both A and B in constituents.\nfn df_mul_entry(a_slot: u32, b_slot: u32, r: u32, c: u32) -> vec2<f32> {\n var acc = vec2<f32>(0.0, 0.0);\n for (var k: u32 = 0u; k < 4u; k = k + 1u) {\n acc = df_add(acc, df_mul(read_entry(a_slot, r, k), read_entry(b_slot, k, c)));\n }\n return acc;\n}\n\n// Compute one full row of (A \u00B7 B), returns 4 df32 entries.\nfn df_mul_row(a_slot: u32, b_slot: u32, r: u32) -> array<vec2<f32>, 4> {\n var out: array<vec2<f32>, 4>;\n for (var c: u32 = 0u; c < 4u; c = c + 1u) {\n out[c] = df_mul_entry(a_slot, b_slot, r, c);\n }\n return out;\n}\n\n// Triple product (A \u00B7 B \u00B7 C) entry (r, c). Uses 4 df_muls per entry\n// \u2014 recomputes the inner row each call. Acceptable: at most one\n// such recipe per RO and only on dirty frames.\nfn df_mul3_entry(a_slot: u32, b_slot: u32, c_slot: u32, r: u32, c: u32) -> vec2<f32> {\n // (A\u00B7B\u00B7C)[r,c] = sum_k (A\u00B7B)[r,k] \u00B7 C[k,c]\n var acc = vec2<f32>(0.0, 0.0);\n for (var k: u32 = 0u; k < 4u; k = k + 1u) {\n let ab_rk = df_mul_entry(a_slot, b_slot, r, k);\n acc = df_add(acc, df_mul(ab_rk, read_entry(c_slot, k, c)));\n }\n return acc;\n}\n\n// \u2500\u2500\u2500 Writers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// Mat4: 16 contiguous f32s, row-major.\n// Mat3: 3 rows \u00D7 4-stride (std140 mat3<f32>), 12 f32s; last column\n// per row left untouched.\n\nfn write_mat4_entry(out_byte: u32, row: u32, col: u32, val: f32) {\n MainHeap[(out_byte >> 2u) + row * 4u + col] = val;\n}\n\nfn write_mat3_entry(out_byte: u32, row: u32, col: u32, val: f32) {\n MainHeap[(out_byte >> 2u) + row * 4u + col] = val;\n}\n\n// \u2500\u2500\u2500 Recipe arms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfn run_collapse_mat4(in0: u32, out_byte: u32) {\n for (var r: u32 = 0u; r < 4u; r = r + 1u) {\n for (var c: u32 = 0u; c < 4u; c = c + 1u) {\n let e = read_entry(in0, r, c);\n write_mat4_entry(out_byte, r, c, e.x + e.y);\n }\n }\n}\n\n// NormalMatrix: (M\u207B\u00B9)\u1D40 upper-3\u00D73.\n// NM[i, j] = MInv[j, i]\nfn run_collapse_mat3_normal(in0: u32, out_byte: u32) {\n for (var i: u32 = 0u; i < 3u; i = i + 1u) {\n for (var j: u32 = 0u; j < 3u; j = j + 1u) {\n let e = read_entry(in0, j, i);\n write_mat3_entry(out_byte, i, j, e.x + e.y);\n }\n }\n}\n\nfn run_dfmul2_collapse(in0: u32, in1: u32, out_byte: u32) {\n for (var r: u32 = 0u; r < 4u; r = r + 1u) {\n for (var c: u32 = 0u; c < 4u; c = c + 1u) {\n let e = df_mul_entry(in0, in1, r, c);\n write_mat4_entry(out_byte, r, c, e.x + e.y);\n }\n }\n}\n\nfn run_dfmul3_collapse(in0: u32, in1: u32, in2: u32, out_byte: u32) {\n for (var r: u32 = 0u; r < 4u; r = r + 1u) {\n for (var c: u32 = 0u; c < 4u; c = c + 1u) {\n let e = df_mul3_entry(in0, in1, in2, r, c);\n write_mat4_entry(out_byte, r, c, e.x + e.y);\n }\n }\n}\n\n// \u2500\u2500\u2500 Entry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) gid: vec3<u32>) {\n if (gid.x >= Count.count) { return; }\n let r = Records[gid.x];\n switch r.recipe_id {\n case 0u: { run_collapse_mat4(r.in0, r.out_byte); } // ModelTrafo\n case 1u: { run_collapse_mat4(r.in0, r.out_byte); } // ModelTrafoInv\n case 2u: { run_collapse_mat3_normal(r.in0, r.out_byte); } // NormalMatrix\n case 3u: { run_dfmul2_collapse(r.in0, r.in1, r.out_byte); } // ModelViewTrafo\n case 4u: { run_dfmul2_collapse(r.in0, r.in1, r.out_byte); } // ModelViewTrafoInv\n case 5u: { run_dfmul3_collapse(r.in0, r.in1, r.in2, r.out_byte); } // ModelViewProjTrafo\n case 6u: { run_dfmul3_collapse(r.in0, r.in1, r.in2, r.out_byte); } // ModelViewProjTrafoInv\n case 7u: { run_collapse_mat4(r.in0, r.out_byte); } // ViewTrafo\n case 8u: { run_collapse_mat4(r.in0, r.out_byte); } // ViewTrafoInv\n case 9u: { run_dfmul2_collapse(r.in0, r.in1, r.out_byte); } // ViewProjTrafo\n case 10u:{ run_dfmul2_collapse(r.in0, r.in1, r.out_byte); } // ViewProjTrafoInv\n case 11u:{ run_collapse_mat4(r.in0, r.out_byte); } // ProjTrafo\n case 12u:{ run_collapse_mat4(r.in0, r.out_byte); } // ProjTrafoInv\n default: { return; }\n }\n}\n\n";
|
|
2
|
+
/** Records are 5× u32 = 20 bytes. WGSL storage struct alignment of
|
|
3
|
+
* 4 means the array stride is 20 bytes. */
|
|
4
|
+
export declare const RECORD_STRIDE_BYTES = 24;
|
|
5
|
+
export declare const RECORD_STRIDE_U32 = 6;
|
|
6
|
+
export declare const RECORD_FIELD: {
|
|
7
|
+
readonly recipe_id: 0;
|
|
8
|
+
readonly in0: 1;
|
|
9
|
+
readonly in1: 2;
|
|
10
|
+
readonly in2: 3;
|
|
11
|
+
readonly out_byte: 4;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=uberKernel.wgsl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uberKernel.wgsl.d.ts","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/uberKernel.wgsl.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,wBAAwB,y0QA4LpC,CAAC;AAEF;4CAC4C;AAC5C,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC"}
|