@aardworx/wombat.rendering 0.21.2 → 0.21.4
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aardworx/wombat.rendering",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.4",
|
|
4
4
|
"description": "WebGPU rendering layer for the Wombat TypeScript stack — RenderObject/RenderTask/runtime + window glue, port of Aardvark.Rendering's lower layers on top of WebGPU and wombat.shader.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "krauthaufen",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"src"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@aardworx/wombat.adaptive": "^0.
|
|
59
|
-
"@aardworx/wombat.base": "^0.
|
|
58
|
+
"@aardworx/wombat.adaptive": "^0.3.0",
|
|
59
|
+
"@aardworx/wombat.base": "^0.6.0",
|
|
60
60
|
"@aardworx/wombat.shader": "^0.6.5"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
package/src/core/renderObject.ts
CHANGED
|
@@ -129,4 +129,29 @@ export interface RenderObject {
|
|
|
129
129
|
* See docs/gpu-transform-propagation.md.
|
|
130
130
|
*/
|
|
131
131
|
readonly modelChain?: readonly aval<import("@aardworx/wombat.base").Trafo3d>[];
|
|
132
|
+
/**
|
|
133
|
+
* Producer-asserted heap eligibility. When `true`, the hybrid
|
|
134
|
+
* partition routes this RO to the heap path WITHOUT building the
|
|
135
|
+
* per-RO reactive `isHeapEligible` predicate — for an RO with an
|
|
136
|
+
* adaptive `drawCall` that predicate is a live custom aval + a
|
|
137
|
+
* negation aval + their subscriptions, retained per RO for the
|
|
138
|
+
* scene's lifetime; at collection scale (thousands of row-shaped
|
|
139
|
+
* ROs) that is pure ballast because the producer already knows the
|
|
140
|
+
* answer statically.
|
|
141
|
+
*
|
|
142
|
+
* The producer GUARANTEES, for the RO's whole lifetime:
|
|
143
|
+
* - every attribute/index buffer aval resolves to `kind: "host"`,
|
|
144
|
+
* - ≤ 1 distinct texture aval and ≤ 1 distinct sampler aval,
|
|
145
|
+
* each heap-servable; no `storageBuffers`,
|
|
146
|
+
* - index format (if indexed) is uint16/uint32,
|
|
147
|
+
* - `drawCall.firstInstance === 0`; non-indexed ⇒
|
|
148
|
+
* `firstVertex === 0`; `instanceCount ≥ 0` (0 draws nothing),
|
|
149
|
+
* - payload stays within the heap ingest budget.
|
|
150
|
+
*
|
|
151
|
+
* Only the global `heapEnabled` toggle still applies (one shared
|
|
152
|
+
* aval per scene). A wrong assertion produces wrong routing —
|
|
153
|
+
* intended for scene-graph layers that verify these conditions
|
|
154
|
+
* once per template, never for hand-built ROs.
|
|
155
|
+
*/
|
|
156
|
+
readonly heapAsserted?: boolean;
|
|
132
157
|
}
|
|
@@ -605,7 +605,11 @@ export function renderObjectToHeapSpec(
|
|
|
605
605
|
pipelineState: ro.pipelineState,
|
|
606
606
|
inputs,
|
|
607
607
|
...(instanceAttributes !== undefined ? { instanceAttributes } : {}),
|
|
608
|
-
|
|
608
|
+
// ≠ 1 (not > 1): instanceCount 0 must flow through — the scan
|
|
609
|
+
// kernel emits indexCount × 0 = nothing, matching what the legacy
|
|
610
|
+
// path draws for zero instances. Omitting it would default to 1
|
|
611
|
+
// and pack a garbage instance from empty per-instance arrays.
|
|
612
|
+
...(dc.instanceCount !== 1 ? { instanceCount: dc.instanceCount } : {}),
|
|
609
613
|
...geom,
|
|
610
614
|
...(textures !== undefined ? { textures } : {}),
|
|
611
615
|
...(ro.injectedStorage !== undefined && ro.injectedStorage.count > 0
|
|
@@ -202,9 +202,16 @@ export function compileHybridScene(
|
|
|
202
202
|
// The per-RO eligibility is ANDed with the global `heapEnabled`
|
|
203
203
|
// toggle — flipping that off forces every RO to legacy.
|
|
204
204
|
const heapEnabled = opts.heapEnabled ?? AVal.constant(true);
|
|
205
|
+
// Producer-asserted ROs (`heapAsserted: true`) skip the per-RO
|
|
206
|
+
// predicate entirely — they all share these TWO scene-level avals
|
|
207
|
+
// instead of two live avals each (see RenderObject.heapAsserted).
|
|
208
|
+
const notHeapEnabled = heapEnabled.isConstant
|
|
209
|
+
? AVal.constant(!heapEnabled.force(/* allow-force */))
|
|
210
|
+
: heapEnabled.map(b => !b);
|
|
205
211
|
const eligCache = new WeakMap<RenderObject, aval<boolean>>();
|
|
206
212
|
const notEligCache = new WeakMap<RenderObject, aval<boolean>>();
|
|
207
213
|
const elig = (ro: RenderObject): aval<boolean> => {
|
|
214
|
+
if (ro.heapAsserted === true) return heapEnabled;
|
|
208
215
|
let av = eligCache.get(ro);
|
|
209
216
|
if (av === undefined) {
|
|
210
217
|
const perRO = isHeapEligible(ro);
|
|
@@ -218,6 +225,7 @@ export function compileHybridScene(
|
|
|
218
225
|
return av;
|
|
219
226
|
};
|
|
220
227
|
const notElig = (ro: RenderObject): aval<boolean> => {
|
|
228
|
+
if (ro.heapAsserted === true) return notHeapEnabled;
|
|
221
229
|
let av = notEligCache.get(ro);
|
|
222
230
|
if (av === undefined) {
|
|
223
231
|
const e = elig(ro);
|