@zephyr3d/editor 0.3.7 → 0.3.8
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/assets/{index-ySiLtSxz.js → index-BZ1L8ggE.js} +43 -3
- package/dist/assistant/zephyr-types-index.json +13230 -9488
- package/dist/images/icon1024.png +0 -0
- package/dist/index.html +1 -1
- package/dist/modules/zephyr3d_backend-webgl.js +2 -0
- package/dist/modules/zephyr3d_backend-webgl.js.map +1 -1
- package/dist/modules/zephyr3d_backend-webgpu.js +457 -16
- package/dist/modules/zephyr3d_backend-webgpu.js.map +1 -1
- package/dist/modules/zephyr3d_device.js +27 -0
- package/dist/modules/zephyr3d_device.js.map +1 -1
- package/dist/modules/zephyr3d_loaders.js +208 -1
- package/dist/modules/zephyr3d_loaders.js.map +1 -1
- package/dist/modules/zephyr3d_scene.js +774 -80
- package/dist/modules/zephyr3d_scene.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgl/dist/capabilities_webgl.js +2 -0
- package/dist/vendor/zephyr3d/backend-webgl/dist/capabilities_webgl.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/capabilities_webgpu.js +2 -0
- package/dist/vendor/zephyr3d/backend-webgpu/dist/capabilities_webgpu.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/commandqueue.js +55 -10
- package/dist/vendor/zephyr3d/backend-webgpu/dist/commandqueue.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/computepass_webgpu.js +4 -0
- package/dist/vendor/zephyr3d/backend-webgpu/dist/computepass_webgpu.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/device.js +44 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/device.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/renderpass_webgpu.js +58 -5
- package/dist/vendor/zephyr3d/backend-webgpu/dist/renderpass_webgpu.js.map +1 -1
- package/dist/vendor/zephyr3d/backend-webgpu/dist/timestamp_query.js +297 -0
- package/dist/vendor/zephyr3d/backend-webgpu/dist/timestamp_query.js.map +1 -0
- package/dist/vendor/zephyr3d/device/dist/base_types.js.map +1 -1
- package/dist/vendor/zephyr3d/device/dist/device.js +27 -0
- package/dist/vendor/zephyr3d/device/dist/device.js.map +1 -1
- package/dist/vendor/zephyr3d/device/dist/index.d.ts +81 -1
- package/dist/vendor/zephyr3d/loaders/dist/gltf/gltf_importer.js +208 -1
- package/dist/vendor/zephyr3d/loaders/dist/gltf/gltf_importer.js.map +1 -1
- package/dist/vendor/zephyr3d/loaders/dist/index.d.ts +8 -0
- package/dist/vendor/zephyr3d/scene/dist/animation/animationset.js +334 -63
- package/dist/vendor/zephyr3d/scene/dist/animation/animationset.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/animation/morphtargetgrouptrack.js +66 -0
- package/dist/vendor/zephyr3d/scene/dist/animation/morphtargetgrouptrack.js.map +1 -0
- package/dist/vendor/zephyr3d/scene/dist/asset/model.js +9 -0
- package/dist/vendor/zephyr3d/scene/dist/asset/model.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/index.d.ts +260 -4
- package/dist/vendor/zephyr3d/scene/dist/index.js +7 -0
- package/dist/vendor/zephyr3d/scene/dist/index.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/posteffect/sao.js +1 -1
- package/dist/vendor/zephyr3d/scene/dist/posteffect/sao.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/executor.js +270 -1
- package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/forward_plus_builder.js +19 -1
- package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/render/rendergraph/types.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/scene/scene.js +1 -0
- package/dist/vendor/zephyr3d/scene/dist/scene/scene.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js +2 -1
- package/dist/vendor/zephyr3d/scene/dist/utility/serialization/manager.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js +70 -1
- package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/vendor/zephyr3d/scene/dist/utility/serialization/scene/camera.js.map +1 -1
- package/package.json +6 -6
- package/dist/vendor/zephyr3d/scene/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/vendor/zephyr3d/scene/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { RGHandle } from './types.js';
|
|
2
|
+
import { getDevice } from '../../app/api.js';
|
|
2
3
|
|
|
4
|
+
const DEFAULT_PROFILING_OPTIONS = {
|
|
5
|
+
enabled: false,
|
|
6
|
+
graph: true,
|
|
7
|
+
pass: true,
|
|
8
|
+
subpass: true,
|
|
9
|
+
includePendingUploads: true,
|
|
10
|
+
allowCrossFrame: false,
|
|
11
|
+
maxPendingFrames: 3,
|
|
12
|
+
label: 'RenderGraph'
|
|
13
|
+
};
|
|
3
14
|
/**
|
|
4
15
|
* Executes a compiled render graph with automatic resource lifecycle management.
|
|
5
16
|
*
|
|
@@ -16,6 +27,11 @@ import { RGHandle } from './types.js';
|
|
|
16
27
|
* @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).
|
|
17
28
|
* @public
|
|
18
29
|
*/ class RenderGraphExecutor {
|
|
30
|
+
static _defaultProfilingOptions = false;
|
|
31
|
+
static _latestProfileResult = null;
|
|
32
|
+
static _latestPendingProfileFrame = null;
|
|
33
|
+
static _latestResolvedProfileSerial = 0;
|
|
34
|
+
static _nextProfileSerial = 0;
|
|
19
35
|
/** @internal */ _allocator;
|
|
20
36
|
/** @internal */ _backbufferWidth;
|
|
21
37
|
/** @internal */ _backbufferHeight;
|
|
@@ -25,10 +41,45 @@ import { RGHandle } from './types.js';
|
|
|
25
41
|
/** @internal */ _importedTextureAliases = new Map();
|
|
26
42
|
/** @internal */ _resolvedImportedTextures = new Map();
|
|
27
43
|
/** @internal */ _cleanupCallbacks = [];
|
|
28
|
-
|
|
44
|
+
/** @internal */ _profilingOptions;
|
|
45
|
+
/** @internal */ _pendingProfileFrames = [];
|
|
46
|
+
/** @internal */ _latestProfileResult = null;
|
|
47
|
+
/** @internal */ _latestResolvedProfileSerial = 0;
|
|
48
|
+
constructor(allocator, backbufferWidth, backbufferHeight, options){
|
|
29
49
|
this._allocator = allocator;
|
|
30
50
|
this._backbufferWidth = backbufferWidth;
|
|
31
51
|
this._backbufferHeight = backbufferHeight;
|
|
52
|
+
this._profilingOptions = this._normalizeProfilingOptions(options?.profiling ?? RenderGraphExecutor._defaultProfilingOptions, options?.device);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set the default profiling options used by newly constructed render graph executors.
|
|
56
|
+
*/ static setDefaultProfilingOptions(options) {
|
|
57
|
+
RenderGraphExecutor._defaultProfilingOptions = options;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the latest resolved profile result from any render graph executor.
|
|
61
|
+
*/ static getLatestProfileResult() {
|
|
62
|
+
return RenderGraphExecutor._latestProfileResult;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the latest pending render graph profile result from any executor.
|
|
66
|
+
*/ static resolveProfileResult() {
|
|
67
|
+
return RenderGraphExecutor._latestPendingProfileFrame?.resolvePromise ?? Promise.resolve(RenderGraphExecutor._latestProfileResult);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Enable, disable, or update timestamp profiling for this executor.
|
|
71
|
+
*/ setProfilingOptions(options) {
|
|
72
|
+
this._profilingOptions = this._normalizeProfilingOptions(options, this._profilingOptions.device);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the latest resolved profile result produced by this executor.
|
|
76
|
+
*/ getLatestProfileResult() {
|
|
77
|
+
return this._latestProfileResult;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the latest pending profile result produced by this executor.
|
|
81
|
+
*/ resolveProfileResult() {
|
|
82
|
+
return this._pendingProfileFrames[this._pendingProfileFrames.length - 1]?.resolvePromise ?? Promise.resolve(this._latestProfileResult);
|
|
32
83
|
}
|
|
33
84
|
/**
|
|
34
85
|
* Update the backbuffer dimensions used for 'backbuffer-relative' sizing.
|
|
@@ -56,6 +107,7 @@ import { RGHandle } from './types.js';
|
|
|
56
107
|
*/ execute(compiled) {
|
|
57
108
|
this._cleanupCallbacks.length = 0;
|
|
58
109
|
this._resolveImportedTextureAliases(compiled);
|
|
110
|
+
const profileFrame = this._beginProfileFrame();
|
|
59
111
|
// Build per-pass allocation and release schedules
|
|
60
112
|
const allocateAt = new Map(); // passIndex -> transient texture resourceIds to allocate
|
|
61
113
|
const releaseAt = new Map(); // passIndex -> transient texture resourceIds to release
|
|
@@ -111,15 +163,19 @@ import { RGHandle } from './types.js';
|
|
|
111
163
|
// Execute the pass with exception safety for resource cleanup.
|
|
112
164
|
// Release errors must not hide the original pass execution error.
|
|
113
165
|
let passError = null;
|
|
166
|
+
const passProfile = this._beginPassProfileScope(profileFrame, pass);
|
|
114
167
|
try {
|
|
115
168
|
if (pass.subpasses.length > 0) {
|
|
116
169
|
const accessScope = this._createAccessScope(pass);
|
|
117
170
|
const ctx = this._createContext(accessScope);
|
|
118
171
|
for (const subpass of pass.subpasses){
|
|
172
|
+
const subpassProfile = this._beginSubpassProfileScope(profileFrame, passProfile, pass, subpass.name);
|
|
119
173
|
try {
|
|
120
174
|
subpass.executeFn(ctx, pass.data);
|
|
121
175
|
} catch (e) {
|
|
122
176
|
throw this._wrapSubpassError(pass.name, subpass.name, e);
|
|
177
|
+
} finally{
|
|
178
|
+
this._endProfileScope(profileFrame, subpassProfile);
|
|
123
179
|
}
|
|
124
180
|
}
|
|
125
181
|
} else if (pass.executeFn) {
|
|
@@ -129,6 +185,8 @@ import { RGHandle } from './types.js';
|
|
|
129
185
|
}
|
|
130
186
|
} catch (e) {
|
|
131
187
|
passError = e;
|
|
188
|
+
} finally{
|
|
189
|
+
this._endProfileScope(profileFrame, passProfile);
|
|
132
190
|
}
|
|
133
191
|
let releaseError = null;
|
|
134
192
|
const framebuffersToRelease = releaseFramebufferAt.get(i);
|
|
@@ -171,6 +229,7 @@ import { RGHandle } from './types.js';
|
|
|
171
229
|
} catch (e) {
|
|
172
230
|
executionError = e;
|
|
173
231
|
} finally{
|
|
232
|
+
this._finishProfileFrame(profileFrame);
|
|
174
233
|
let cleanupError = null;
|
|
175
234
|
try {
|
|
176
235
|
this._runCleanupCallbacks();
|
|
@@ -212,6 +271,216 @@ import { RGHandle } from './types.js';
|
|
|
212
271
|
this._resolvedImportedTextures.clear();
|
|
213
272
|
}
|
|
214
273
|
// ─── Private ────────────────────────────────────────────────────────
|
|
274
|
+
/** @internal */ _normalizeProfilingOptions(options, fallbackDevice) {
|
|
275
|
+
const source = typeof options === 'object' ? options : {};
|
|
276
|
+
const enabled = typeof options === 'boolean' ? options : source.enabled ?? true;
|
|
277
|
+
return {
|
|
278
|
+
enabled,
|
|
279
|
+
graph: source.graph ?? DEFAULT_PROFILING_OPTIONS.graph,
|
|
280
|
+
pass: source.pass ?? DEFAULT_PROFILING_OPTIONS.pass,
|
|
281
|
+
subpass: source.subpass ?? DEFAULT_PROFILING_OPTIONS.subpass,
|
|
282
|
+
includePendingUploads: source.includePendingUploads ?? DEFAULT_PROFILING_OPTIONS.includePendingUploads,
|
|
283
|
+
allowCrossFrame: source.allowCrossFrame ?? DEFAULT_PROFILING_OPTIONS.allowCrossFrame,
|
|
284
|
+
maxPendingFrames: Math.max(1, source.maxPendingFrames ?? DEFAULT_PROFILING_OPTIONS.maxPendingFrames),
|
|
285
|
+
label: source.label ?? DEFAULT_PROFILING_OPTIONS.label,
|
|
286
|
+
device: source.device ?? fallbackDevice
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/** @internal */ _getProfilingDevice() {
|
|
290
|
+
if (this._profilingOptions.device) {
|
|
291
|
+
return this._profilingOptions.device;
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
return getDevice();
|
|
295
|
+
} catch {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** @internal */ _beginProfileFrame() {
|
|
300
|
+
if (!this._profilingOptions.enabled) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
const device = this._getProfilingDevice();
|
|
304
|
+
const supported = !!device?.getDeviceCaps().miscCaps.supportTimestampQuery;
|
|
305
|
+
const rootResult = {
|
|
306
|
+
name: this._profilingOptions.label,
|
|
307
|
+
type: 'graph',
|
|
308
|
+
queryId: 0,
|
|
309
|
+
durationMs: 0,
|
|
310
|
+
status: supported ? 'resolved' : 'unsupported',
|
|
311
|
+
children: [],
|
|
312
|
+
message: supported ? undefined : 'GPU timestamp queries are not supported'
|
|
313
|
+
};
|
|
314
|
+
const result = {
|
|
315
|
+
frameId: device?.frameInfo.frameCounter ?? -1,
|
|
316
|
+
status: rootResult.status,
|
|
317
|
+
graph: rootResult,
|
|
318
|
+
passes: rootResult.children
|
|
319
|
+
};
|
|
320
|
+
const root = {
|
|
321
|
+
result: rootResult,
|
|
322
|
+
queryId: 0,
|
|
323
|
+
ended: false
|
|
324
|
+
};
|
|
325
|
+
const frame = {
|
|
326
|
+
serial: ++RenderGraphExecutor._nextProfileSerial,
|
|
327
|
+
device,
|
|
328
|
+
supported,
|
|
329
|
+
result,
|
|
330
|
+
root,
|
|
331
|
+
scopes: [],
|
|
332
|
+
resolvePromise: Promise.resolve(result)
|
|
333
|
+
};
|
|
334
|
+
if (this._profilingOptions.graph) {
|
|
335
|
+
this._beginTimestampScope(frame, root, this._profilingOptions.label);
|
|
336
|
+
}
|
|
337
|
+
return frame;
|
|
338
|
+
}
|
|
339
|
+
/** @internal */ _beginPassProfileScope(frame, pass) {
|
|
340
|
+
if (!frame || !this._profilingOptions.pass && !this._profilingOptions.subpass) {
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
return this._beginProfileScope(frame, frame.root, 'pass', pass.name, this._profilingOptions.pass);
|
|
344
|
+
}
|
|
345
|
+
/** @internal */ _beginSubpassProfileScope(frame, passScope, pass, subpassName) {
|
|
346
|
+
if (!frame || !this._profilingOptions.subpass) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const parent = passScope ?? frame.root;
|
|
350
|
+
return this._beginProfileScope(frame, parent, 'subpass', subpassName, true, `${pass.name}/${subpassName}`);
|
|
351
|
+
}
|
|
352
|
+
/** @internal */ _beginProfileScope(frame, parent, type, name, queryEnabled, queryLabel) {
|
|
353
|
+
const status = frame.supported && !queryEnabled ? 'resolved' : frame.supported ? 'pending' : 'unsupported';
|
|
354
|
+
const result = {
|
|
355
|
+
name,
|
|
356
|
+
type,
|
|
357
|
+
queryId: 0,
|
|
358
|
+
durationMs: 0,
|
|
359
|
+
status,
|
|
360
|
+
children: [],
|
|
361
|
+
message: frame.supported ? undefined : 'GPU timestamp queries are not supported'
|
|
362
|
+
};
|
|
363
|
+
parent.result.children.push(result);
|
|
364
|
+
const scope = {
|
|
365
|
+
result,
|
|
366
|
+
queryId: 0,
|
|
367
|
+
ended: false
|
|
368
|
+
};
|
|
369
|
+
if (queryEnabled) {
|
|
370
|
+
this._beginTimestampScope(frame, scope, queryLabel ?? name);
|
|
371
|
+
}
|
|
372
|
+
return scope;
|
|
373
|
+
}
|
|
374
|
+
/** @internal */ _beginTimestampScope(frame, scope, label) {
|
|
375
|
+
if (!frame.supported || !frame.device) {
|
|
376
|
+
scope.result.status = 'unsupported';
|
|
377
|
+
scope.result.message = 'GPU timestamp queries are not supported';
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const queryId = frame.device.beginTimestampQuery(label, {
|
|
381
|
+
includePendingUploads: this._profilingOptions.includePendingUploads,
|
|
382
|
+
allowCrossFrame: this._profilingOptions.allowCrossFrame
|
|
383
|
+
});
|
|
384
|
+
scope.queryId = queryId;
|
|
385
|
+
scope.result.queryId = queryId;
|
|
386
|
+
if (queryId > 0) {
|
|
387
|
+
scope.result.status = 'pending';
|
|
388
|
+
frame.scopes.push(scope);
|
|
389
|
+
} else {
|
|
390
|
+
scope.result.status = 'unsupported';
|
|
391
|
+
scope.result.message = 'GPU timestamp query was not started';
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/** @internal */ _endProfileScope(frame, scope) {
|
|
395
|
+
if (!frame || !frame.device || !scope || scope.ended) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
scope.ended = true;
|
|
399
|
+
if (scope.queryId > 0) {
|
|
400
|
+
frame.device.endTimestampQuery(scope.queryId);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/** @internal */ _finishProfileFrame(frame) {
|
|
404
|
+
if (!frame) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
this._endProfileScope(frame, frame.root);
|
|
408
|
+
if (frame.scopes.length === 0 || !frame.device) {
|
|
409
|
+
frame.result.status = this._aggregateProfileStatus(frame.result.graph);
|
|
410
|
+
this._publishProfileResult(frame);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
frame.resolvePromise = Promise.all(frame.scopes.map((scope)=>frame.device.resolveTimestampQuery(scope.queryId))).then((results)=>{
|
|
414
|
+
for(let i = 0; i < results.length; i++){
|
|
415
|
+
this._applyTimestampResult(frame.scopes[i], results[i]);
|
|
416
|
+
}
|
|
417
|
+
frame.result.status = this._aggregateProfileStatus(frame.result.graph);
|
|
418
|
+
this._publishProfileResult(frame);
|
|
419
|
+
return frame.result;
|
|
420
|
+
}).catch((err)=>{
|
|
421
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
422
|
+
for (const scope of frame.scopes){
|
|
423
|
+
scope.result.status = 'failed';
|
|
424
|
+
scope.result.message = message;
|
|
425
|
+
}
|
|
426
|
+
frame.result.status = 'failed';
|
|
427
|
+
this._publishProfileResult(frame);
|
|
428
|
+
return frame.result;
|
|
429
|
+
});
|
|
430
|
+
this._trackPendingProfileFrame(frame);
|
|
431
|
+
}
|
|
432
|
+
/** @internal */ _trackPendingProfileFrame(frame) {
|
|
433
|
+
this._pendingProfileFrames.push(frame);
|
|
434
|
+
while(this._pendingProfileFrames.length > this._profilingOptions.maxPendingFrames){
|
|
435
|
+
this._pendingProfileFrames.shift();
|
|
436
|
+
}
|
|
437
|
+
RenderGraphExecutor._latestPendingProfileFrame = frame;
|
|
438
|
+
}
|
|
439
|
+
/** @internal */ _publishProfileResult(frame) {
|
|
440
|
+
this._pendingProfileFrames = this._pendingProfileFrames.filter((pending)=>pending !== frame);
|
|
441
|
+
if (frame.serial >= this._latestResolvedProfileSerial) {
|
|
442
|
+
this._latestResolvedProfileSerial = frame.serial;
|
|
443
|
+
this._latestProfileResult = frame.result;
|
|
444
|
+
}
|
|
445
|
+
if (frame.serial >= RenderGraphExecutor._latestResolvedProfileSerial) {
|
|
446
|
+
RenderGraphExecutor._latestResolvedProfileSerial = frame.serial;
|
|
447
|
+
RenderGraphExecutor._latestProfileResult = frame.result;
|
|
448
|
+
}
|
|
449
|
+
if (RenderGraphExecutor._latestPendingProfileFrame === frame) {
|
|
450
|
+
RenderGraphExecutor._latestPendingProfileFrame = null;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/** @internal */ _applyTimestampResult(scope, result) {
|
|
454
|
+
scope.result.queryId = result.id;
|
|
455
|
+
scope.result.durationMs = result.durationMs;
|
|
456
|
+
scope.result.status = result.status;
|
|
457
|
+
scope.result.message = result.message;
|
|
458
|
+
}
|
|
459
|
+
/** @internal */ _aggregateProfileStatus(scope) {
|
|
460
|
+
const statuses = [];
|
|
461
|
+
const collect = (node)=>{
|
|
462
|
+
statuses.push(node.status);
|
|
463
|
+
for (const child of node.children){
|
|
464
|
+
collect(child);
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
collect(scope);
|
|
468
|
+
for (const status of [
|
|
469
|
+
'failed',
|
|
470
|
+
'invalid',
|
|
471
|
+
'exhausted',
|
|
472
|
+
'pending',
|
|
473
|
+
'auto-closed'
|
|
474
|
+
]){
|
|
475
|
+
if (statuses.includes(status)) {
|
|
476
|
+
return status;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (statuses.includes('unsupported')) {
|
|
480
|
+
return 'unsupported';
|
|
481
|
+
}
|
|
482
|
+
return 'resolved';
|
|
483
|
+
}
|
|
215
484
|
/** @internal */ _resolveSize(desc) {
|
|
216
485
|
const mode = desc.sizeMode ?? 'backbuffer-relative';
|
|
217
486
|
if (mode === 'absolute') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sources":["../../../src/render/rendergraph/executor.ts"],"sourcesContent":["import type {\r\n CompiledRenderGraph,\r\n RGTextureAllocator,\r\n RGTextureDesc,\r\n RGFramebufferDesc,\r\n RGResolvedSize,\r\n RGExecuteContext,\r\n RGExecuteFn,\r\n RGPass\r\n} from './types';\r\nimport { RGHandle } from './types';\r\n\r\ninterface RGPassAccessScope {\r\n passName: string;\r\n accessibleIds: Set<number>;\r\n textureIds: Set<number>;\r\n framebufferIds: Set<number>;\r\n}\r\n\r\n/**\r\n * Executes a compiled render graph with automatic resource lifecycle management.\r\n *\r\n * The executor allocates transient textures before their first use and releases\r\n * them after their last use, using the provided {@link RGTextureAllocator}.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const executor = new RenderGraphExecutor(myAllocator, backbufferWidth, backbufferHeight);\r\n * executor.setImportedTexture(backbufferHandle, actualBackbufferTexture);\r\n * executor.execute(compiledGraph);\r\n * ```\r\n *\r\n * @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).\r\n * @public\r\n */\r\nexport class RenderGraphExecutor<TTexture = unknown, TFramebuffer = unknown> {\r\n /** @internal */\r\n private _allocator: RGTextureAllocator<TTexture, TFramebuffer>;\r\n /** @internal */\r\n private _backbufferWidth: number;\r\n /** @internal */\r\n private _backbufferHeight: number;\r\n /** @internal */\r\n private _importedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _allocatedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _allocatedFramebuffers: Map<number, TFramebuffer> = new Map();\r\n /** @internal */\r\n private _importedTextureAliases: Map<number, number> = new Map();\r\n /** @internal */\r\n private _resolvedImportedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _cleanupCallbacks: Array<() => void> = [];\r\n\r\n constructor(\r\n allocator: RGTextureAllocator<TTexture, TFramebuffer>,\r\n backbufferWidth: number,\r\n backbufferHeight: number\r\n ) {\r\n this._allocator = allocator;\r\n this._backbufferWidth = backbufferWidth;\r\n this._backbufferHeight = backbufferHeight;\r\n }\r\n\r\n /**\r\n * Update the backbuffer dimensions used for 'backbuffer-relative' sizing.\r\n */\r\n setBackbufferSize(width: number, height: number): void {\r\n this._backbufferWidth = width;\r\n this._backbufferHeight = height;\r\n }\r\n\r\n /**\r\n * Register an imported (external) texture so it can be resolved during execution.\r\n *\r\n * @param handle - The handle returned from {@link RenderGraph.importTexture}.\r\n * @param texture - The actual GPU texture object.\r\n */\r\n setImportedTexture(handle: RGHandle, texture: TTexture): void {\r\n this._importedTextures.set(handle._id, texture);\r\n }\r\n\r\n /**\r\n * Execute the compiled graph with full resource lifecycle management.\r\n *\r\n * For each pass in topological order:\r\n * 1. Allocate any transient resources whose lifetime begins at this pass\r\n * 2. Invoke the pass's execute callback with a context that resolves handles\r\n * 3. Release any transient resources whose lifetime ends at this pass\r\n *\r\n * @param compiled - The compiled graph from {@link RenderGraph.compile}.\r\n */\r\n execute(compiled: CompiledRenderGraph): void {\r\n this._cleanupCallbacks.length = 0;\r\n this._resolveImportedTextureAliases(compiled);\r\n\r\n // Build per-pass allocation and release schedules\r\n const allocateAt = new Map<number, number[]>(); // passIndex -> transient texture resourceIds to allocate\r\n const releaseAt = new Map<number, number[]>(); // passIndex -> transient texture resourceIds to release\r\n const allocateFramebufferAt = new Map<number, number[]>(); // passIndex -> framebuffer resourceIds to allocate\r\n const releaseFramebufferAt = new Map<number, number[]>(); // passIndex -> framebuffer resourceIds to release\r\n\r\n for (const [resId, lifetime] of compiled.lifetimes) {\r\n if (lifetime.resource.kind === 'transient') {\r\n if (!allocateAt.has(lifetime.firstUse)) {\r\n allocateAt.set(lifetime.firstUse, []);\r\n }\r\n allocateAt.get(lifetime.firstUse)!.push(resId);\r\n\r\n if (!releaseAt.has(lifetime.lastUse)) {\r\n releaseAt.set(lifetime.lastUse, []);\r\n }\r\n releaseAt.get(lifetime.lastUse)!.push(resId);\r\n } else if (lifetime.resource.kind === 'framebuffer') {\r\n if (!allocateFramebufferAt.has(lifetime.firstUse)) {\r\n allocateFramebufferAt.set(lifetime.firstUse, []);\r\n }\r\n allocateFramebufferAt.get(lifetime.firstUse)!.push(resId);\r\n\r\n if (!releaseFramebufferAt.has(lifetime.lastUse)) {\r\n releaseFramebufferAt.set(lifetime.lastUse, []);\r\n }\r\n releaseFramebufferAt.get(lifetime.lastUse)!.push(resId);\r\n }\r\n }\r\n\r\n let completed = false;\r\n let executionError: unknown = null;\r\n try {\r\n for (let i = 0; i < compiled.orderedPasses.length; i++) {\r\n const pass = compiled.orderedPasses[i];\r\n\r\n // Allocate resources that start at this pass\r\n const toAllocate = allocateAt.get(i);\r\n if (toAllocate) {\r\n for (const resId of toAllocate) {\r\n const lifetime = compiled.lifetimes.get(resId)!;\r\n const desc = lifetime.resource.desc as RGTextureDesc;\r\n const size = this._resolveSize(desc);\r\n const texture = this._allocator.allocate(desc, size);\r\n this._allocatedTextures.set(resId, texture);\r\n }\r\n }\r\n\r\n // Allocate framebuffer views after their texture attachments are available.\r\n const framebuffersToAllocate = allocateFramebufferAt.get(i);\r\n if (framebuffersToAllocate) {\r\n for (const resId of framebuffersToAllocate) {\r\n const lifetime = compiled.lifetimes.get(resId)!;\r\n const desc = lifetime.resource.desc as RGFramebufferDesc;\r\n const framebuffer = this._createFramebuffer(this._resolveFramebufferDesc(desc), false);\r\n this._allocatedFramebuffers.set(resId, framebuffer);\r\n }\r\n }\r\n\r\n // Execute the pass with exception safety for resource cleanup.\r\n // Release errors must not hide the original pass execution error.\r\n let passError: unknown = null;\r\n try {\r\n if (pass.subpasses.length > 0) {\r\n const accessScope = this._createAccessScope(pass);\r\n const ctx = this._createContext(accessScope);\r\n for (const subpass of pass.subpasses) {\r\n try {\r\n (subpass.executeFn as RGExecuteFn<unknown>)(ctx, pass.data);\r\n } catch (e) {\r\n throw this._wrapSubpassError(pass.name, subpass.name, e);\r\n }\r\n }\r\n } else if (pass.executeFn) {\r\n const accessScope = this._createAccessScope(pass);\r\n const ctx = this._createContext(accessScope);\r\n (pass.executeFn as RGExecuteFn<unknown>)(ctx, pass.data);\r\n }\r\n } catch (e) {\r\n passError = e;\r\n }\r\n\r\n let releaseError: unknown = null;\r\n const framebuffersToRelease = releaseFramebufferAt.get(i);\r\n if (framebuffersToRelease) {\r\n for (const resId of framebuffersToRelease) {\r\n const framebuffer = this._allocatedFramebuffers.get(resId);\r\n if (framebuffer !== undefined) {\r\n try {\r\n this._releaseFramebuffer(framebuffer);\r\n this._allocatedFramebuffers.delete(resId);\r\n } catch (e) {\r\n releaseError ??= e;\r\n }\r\n }\r\n }\r\n }\r\n // Release resources that end at this pass (always runs even if pass throws)\r\n const toRelease = releaseAt.get(i);\r\n if (toRelease) {\r\n for (const resId of toRelease) {\r\n const texture = this._allocatedTextures.get(resId);\r\n if (texture !== undefined) {\r\n try {\r\n this._allocator.release(texture);\r\n this._allocatedTextures.delete(resId);\r\n } catch (e) {\r\n releaseError ??= e;\r\n }\r\n }\r\n }\r\n }\r\n if (passError) {\r\n throw passError;\r\n }\r\n if (releaseError) {\r\n throw releaseError;\r\n }\r\n }\r\n completed = true;\r\n } catch (e) {\r\n executionError = e;\r\n } finally {\r\n let cleanupError: unknown = null;\r\n try {\r\n this._runCleanupCallbacks();\r\n } catch (e) {\r\n cleanupError = e;\r\n } finally {\r\n if (!completed) {\r\n try {\r\n this.reset();\r\n } catch (e) {\r\n cleanupError ??= e;\r\n }\r\n }\r\n }\r\n if (executionError) {\r\n throw executionError;\r\n }\r\n if (cleanupError) {\r\n throw cleanupError;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear imported texture registrations and any leftover allocated textures.\r\n * Call this after execution or when resetting for a new frame.\r\n */\r\n reset(): void {\r\n this._runCleanupCallbacks();\r\n // Release any textures that weren't released (shouldn't happen in normal flow)\r\n for (const framebuffer of this._allocatedFramebuffers.values()) {\r\n this._releaseFramebuffer(framebuffer);\r\n }\r\n this._allocatedFramebuffers.clear();\r\n for (const texture of this._allocatedTextures.values()) {\r\n this._allocator.release(texture);\r\n }\r\n this._allocatedTextures.clear();\r\n this._importedTextures.clear();\r\n this._importedTextureAliases.clear();\r\n this._resolvedImportedTextures.clear();\r\n }\r\n\r\n // ─── Private ────────────────────────────────────────────────────────\r\n\r\n /** @internal */\r\n private _resolveSize(desc: RGTextureDesc): RGResolvedSize {\r\n const mode = desc.sizeMode ?? 'backbuffer-relative';\r\n if (mode === 'absolute') {\r\n return {\r\n width: desc.width ?? 1,\r\n height: desc.height ?? 1\r\n };\r\n }\r\n // backbuffer-relative: width/height are scale factors (default 1.0)\r\n const scaleX = desc.width ?? 1.0;\r\n const scaleY = desc.height ?? 1.0;\r\n return {\r\n width: Math.max(1, Math.floor(this._backbufferWidth * scaleX)),\r\n height: Math.max(1, Math.floor(this._backbufferHeight * scaleY))\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _resolveImportedTextureAliases(compiled: CompiledRenderGraph): void {\r\n this._importedTextureAliases.clear();\r\n this._resolvedImportedTextures.clear();\r\n const physicalToTexture = new Map<number, TTexture>();\r\n for (const lifetime of compiled.lifetimes.values()) {\r\n const resource = lifetime.resource;\r\n if (resource.kind !== 'imported') {\r\n continue;\r\n }\r\n const texture =\r\n this._importedTextures.get(resource.id) ?? this._importedTextures.get(resource.physicalId);\r\n if (texture !== undefined) {\r\n physicalToTexture.set(resource.physicalId, texture);\r\n }\r\n }\r\n for (const lifetime of compiled.lifetimes.values()) {\r\n const resource = lifetime.resource;\r\n if (resource.kind !== 'imported') {\r\n continue;\r\n }\r\n this._importedTextureAliases.set(resource.id, resource.physicalId);\r\n const texture = physicalToTexture.get(resource.physicalId);\r\n if (texture !== undefined) {\r\n this._resolvedImportedTextures.set(resource.id, texture);\r\n this._resolvedImportedTextures.set(resource.physicalId, texture);\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _runCleanupCallbacks(): void {\r\n let error: unknown = null;\r\n while (this._cleanupCallbacks.length > 0) {\r\n const callback = this._cleanupCallbacks.pop()!;\r\n try {\r\n callback();\r\n } catch (e) {\r\n error ??= e;\r\n }\r\n }\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _createFramebuffer(desc: RGFramebufferDesc, autoCleanup = true): TFramebuffer {\r\n if (!this._allocator.allocateFramebuffer || !this._allocator.releaseFramebuffer) {\r\n throw new Error('RenderGraphExecutor: framebuffer allocation is not supported by this allocator.');\r\n }\r\n const framebuffer = this._allocator.allocateFramebuffer(desc);\r\n if (autoCleanup) {\r\n this._cleanupCallbacks.push(() => {\r\n this._allocator.releaseFramebuffer!(framebuffer);\r\n });\r\n }\r\n return framebuffer;\r\n }\r\n\r\n /** @internal */\r\n private _releaseFramebuffer(framebuffer: TFramebuffer): void {\r\n if (!this._allocator.releaseFramebuffer) {\r\n throw new Error('RenderGraphExecutor: framebuffer release is not supported by this allocator.');\r\n }\r\n this._allocator.releaseFramebuffer(framebuffer);\r\n }\r\n\r\n /** @internal */\r\n private _resolveFramebufferDesc(\r\n desc: RGFramebufferDesc,\r\n accessScope?: RGPassAccessScope\r\n ): RGFramebufferDesc {\r\n const resolveAttachment = (attachment: unknown): unknown => {\r\n if (attachment instanceof RGHandle) {\r\n if (accessScope) {\r\n this._assertDeclaredAccess(accessScope, attachment, 'texture');\r\n }\r\n return this._resolveResource(attachment);\r\n }\r\n return attachment;\r\n };\r\n const colors = Array.isArray(desc.colorAttachments)\r\n ? desc.colorAttachments.map(resolveAttachment)\r\n : desc.colorAttachments\r\n ? resolveAttachment(desc.colorAttachments)\r\n : null;\r\n return {\r\n ...desc,\r\n colorAttachments: colors,\r\n depthAttachment: resolveAttachment(desc.depthAttachment)\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _resolveResource(handle: RGHandle): TTexture {\r\n const imported = this._importedTextures.get(handle._id);\r\n if (imported !== undefined) {\r\n return imported;\r\n }\r\n const resolvedImported = this._resolvedImportedTextures.get(handle._id);\r\n if (resolvedImported !== undefined) {\r\n return resolvedImported;\r\n }\r\n const importedAlias = this._importedTextureAliases.get(handle._id);\r\n if (importedAlias !== undefined) {\r\n const aliased =\r\n this._importedTextures.get(importedAlias) ?? this._resolvedImportedTextures.get(importedAlias);\r\n if (aliased !== undefined) {\r\n return aliased;\r\n }\r\n }\r\n const allocated = this._allocatedTextures.get(handle._id);\r\n if (allocated !== undefined) {\r\n return allocated;\r\n }\r\n throw new Error(\r\n `RenderGraphExecutor: cannot resolve resource \"${handle.name}\" (id=${handle._id}). ` +\r\n `It may not have been allocated yet or was already released.`\r\n );\r\n }\r\n\r\n /** @internal */\r\n private _createAccessScope(pass: RGPass): RGPassAccessScope {\r\n const accessibleIds = new Set<number>();\r\n const textureIds = new Set<number>();\r\n const framebufferIds = new Set<number>();\r\n for (const resource of pass.reads) {\r\n accessibleIds.add(resource.id);\r\n if (resource.kind === 'transient' || resource.kind === 'imported') {\r\n textureIds.add(resource.id);\r\n } else if (resource.kind === 'framebuffer') {\r\n framebufferIds.add(resource.id);\r\n }\r\n }\r\n for (const resource of pass.writes) {\r\n accessibleIds.add(resource.id);\r\n if (resource.kind === 'transient' || resource.kind === 'imported') {\r\n textureIds.add(resource.id);\r\n } else if (resource.kind === 'framebuffer') {\r\n framebufferIds.add(resource.id);\r\n }\r\n }\r\n return {\r\n passName: pass.name,\r\n accessibleIds,\r\n textureIds,\r\n framebufferIds\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _assertDeclaredAccess(\r\n accessScope: RGPassAccessScope,\r\n handle: RGHandle,\r\n access: 'texture' | 'framebuffer'\r\n ): void {\r\n if (!accessScope.accessibleIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access ${access} \"${handle.name}\" ` +\r\n `without declaring a read/write dependency.`\r\n );\r\n }\r\n if (access === 'texture' && !accessScope.textureIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access \"${handle.name}\" as a texture, ` +\r\n `but it is not a texture resource.`\r\n );\r\n }\r\n if (access === 'framebuffer' && !accessScope.framebufferIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access \"${handle.name}\" as a framebuffer, ` +\r\n `but it is not a framebuffer resource.`\r\n );\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _wrapSubpassError(passName: string, subpassName: string, error: unknown): Error {\r\n const message = error instanceof Error ? error.message : String(error);\r\n const wrapped = new Error(\r\n `RenderGraphExecutor: pass \"${passName}\" subpass \"${subpassName}\" failed: ${message}`\r\n );\r\n (wrapped as Error & { cause?: unknown }).cause = error;\r\n return wrapped;\r\n }\r\n\r\n /** @internal */\r\n private _createContext(accessScope: RGPassAccessScope): RGExecuteContext {\r\n const self = this;\r\n return {\r\n getTexture<T>(handle: RGHandle): T {\r\n self._assertDeclaredAccess(accessScope, handle, 'texture');\r\n return self._resolveResource(handle) as unknown as T;\r\n },\r\n getFramebuffer<TFramebuffer = unknown>(handle: RGHandle): TFramebuffer {\r\n self._assertDeclaredAccess(accessScope, handle, 'framebuffer');\r\n const framebuffer = self._allocatedFramebuffers.get(handle._id);\r\n if (framebuffer !== undefined) {\r\n return framebuffer as unknown as TFramebuffer;\r\n }\r\n throw new Error(\r\n `RenderGraphExecutor: cannot resolve framebuffer \"${handle.name}\" (id=${handle._id}). ` +\r\n `It may not have been allocated yet or was already released.`\r\n );\r\n },\r\n createFramebuffer<TFramebuffer = unknown>(desc: RGFramebufferDesc): TFramebuffer {\r\n return self._createFramebuffer(\r\n self._resolveFramebufferDesc(desc, accessScope)\r\n ) as unknown as TFramebuffer;\r\n },\r\n deferCleanup(callback: () => void): void {\r\n self._cleanupCallbacks.push(callback);\r\n }\r\n };\r\n }\r\n}\r\n"],"names":["RenderGraphExecutor","_importedTextures","Map","_allocatedTextures","_allocatedFramebuffers","_importedTextureAliases","_resolvedImportedTextures","_cleanupCallbacks","allocator","backbufferWidth","backbufferHeight","_allocator","_backbufferWidth","_backbufferHeight","setBackbufferSize","width","height","setImportedTexture","handle","texture","set","_id","execute","compiled","length","_resolveImportedTextureAliases","allocateAt","releaseAt","allocateFramebufferAt","releaseFramebufferAt","resId","lifetime","lifetimes","resource","kind","has","firstUse","get","push","lastUse","completed","executionError","i","orderedPasses","pass","toAllocate","desc","size","_resolveSize","allocate","framebuffersToAllocate","framebuffer","_createFramebuffer","_resolveFramebufferDesc","passError","subpasses","accessScope","_createAccessScope","ctx","_createContext","subpass","executeFn","data","e","_wrapSubpassError","name","releaseError","framebuffersToRelease","undefined","_releaseFramebuffer","delete","toRelease","release","cleanupError","_runCleanupCallbacks","reset","values","clear","mode","sizeMode","scaleX","scaleY","Math","max","floor","physicalToTexture","id","physicalId","error","callback","pop","autoCleanup","allocateFramebuffer","releaseFramebuffer","Error","resolveAttachment","attachment","RGHandle","_assertDeclaredAccess","_resolveResource","colors","Array","isArray","colorAttachments","map","depthAttachment","imported","resolvedImported","importedAlias","aliased","allocated","accessibleIds","Set","textureIds","framebufferIds","reads","add","writes","passName","access","subpassName","message","String","wrapped","cause","self","getTexture","getFramebuffer","createFramebuffer","deferCleanup"],"mappings":";;AAmBA;;;;;;;;;;;;;;;AAeC,IACM,MAAMA,mBAAAA,CAAAA;qBAEX,UAA+D;qBAE/D,gBAAiC;qBAEjC,iBAAkC;AAClC,qBACQC,iBAA2C,GAAA,IAAIC,GAAM,EAAA;AAC7D,qBACQC,kBAA4C,GAAA,IAAID,GAAM,EAAA;AAC9D,qBACQE,sBAAoD,GAAA,IAAIF,GAAM,EAAA;AACtE,qBACQG,uBAA+C,GAAA,IAAIH,GAAM,EAAA;AACjE,qBACQI,yBAAmD,GAAA,IAAIJ,GAAM,EAAA;AACrE,qBACQK,iBAAuC,GAAA,EAAE;AAEjD,IAAA,WAAA,CACEC,SAAqD,EACrDC,eAAuB,EACvBC,gBAAwB,CACxB;QACA,IAAI,CAACC,UAAU,GAAGH,SAAAA;QAClB,IAAI,CAACI,gBAAgB,GAAGH,eAAAA;QACxB,IAAI,CAACI,iBAAiB,GAAGH,gBAAAA;AAC3B;AAEA;;AAEC,MACDI,iBAAkBC,CAAAA,KAAa,EAAEC,MAAc,EAAQ;QACrD,IAAI,CAACJ,gBAAgB,GAAGG,KAAAA;QACxB,IAAI,CAACF,iBAAiB,GAAGG,MAAAA;AAC3B;AAEA;;;;;AAKC,MACDC,kBAAmBC,CAAAA,MAAgB,EAAEC,OAAiB,EAAQ;AAC5D,QAAA,IAAI,CAAClB,iBAAiB,CAACmB,GAAG,CAACF,MAAAA,CAAOG,GAAG,EAAEF,OAAAA,CAAAA;AACzC;AAEA;;;;;;;;;MAUAG,OAAAA,CAAQC,QAA6B,EAAQ;AAC3C,QAAA,IAAI,CAAChB,iBAAiB,CAACiB,MAAM,GAAG,CAAA;QAChC,IAAI,CAACC,8BAA8B,CAACF,QAAAA,CAAAA;;QAGpC,MAAMG,UAAAA,GAAa,IAAIxB,GAAAA,EAAAA,CAAAA;QACvB,MAAMyB,SAAAA,GAAY,IAAIzB,GAAAA,EAAAA,CAAAA;QACtB,MAAM0B,qBAAAA,GAAwB,IAAI1B,GAAAA,EAAAA,CAAAA;QAClC,MAAM2B,oBAAAA,GAAuB,IAAI3B,GAAAA,EAAAA,CAAAA;AAEjC,QAAA,KAAK,MAAM,CAAC4B,KAAAA,EAAOC,SAAS,IAAIR,QAAAA,CAASS,SAAS,CAAE;AAClD,YAAA,IAAID,QAASE,CAAAA,QAAQ,CAACC,IAAI,KAAK,WAAa,EAAA;AAC1C,gBAAA,IAAI,CAACR,UAAWS,CAAAA,GAAG,CAACJ,QAAAA,CAASK,QAAQ,CAAG,EAAA;AACtCV,oBAAAA,UAAAA,CAAWN,GAAG,CAACW,QAASK,CAAAA,QAAQ,EAAE,EAAE,CAAA;AACtC;AACAV,gBAAAA,UAAAA,CAAWW,GAAG,CAACN,QAAAA,CAASK,QAAQ,CAAA,CAAGE,IAAI,CAACR,KAAAA,CAAAA;AAExC,gBAAA,IAAI,CAACH,SAAUQ,CAAAA,GAAG,CAACJ,QAAAA,CAASQ,OAAO,CAAG,EAAA;AACpCZ,oBAAAA,SAAAA,CAAUP,GAAG,CAACW,QAASQ,CAAAA,OAAO,EAAE,EAAE,CAAA;AACpC;AACAZ,gBAAAA,SAAAA,CAAUU,GAAG,CAACN,QAAAA,CAASQ,OAAO,CAAA,CAAGD,IAAI,CAACR,KAAAA,CAAAA;AACxC,aAAA,MAAO,IAAIC,QAASE,CAAAA,QAAQ,CAACC,IAAI,KAAK,aAAe,EAAA;AACnD,gBAAA,IAAI,CAACN,qBAAsBO,CAAAA,GAAG,CAACJ,QAAAA,CAASK,QAAQ,CAAG,EAAA;AACjDR,oBAAAA,qBAAAA,CAAsBR,GAAG,CAACW,QAASK,CAAAA,QAAQ,EAAE,EAAE,CAAA;AACjD;AACAR,gBAAAA,qBAAAA,CAAsBS,GAAG,CAACN,QAAAA,CAASK,QAAQ,CAAA,CAAGE,IAAI,CAACR,KAAAA,CAAAA;AAEnD,gBAAA,IAAI,CAACD,oBAAqBM,CAAAA,GAAG,CAACJ,QAAAA,CAASQ,OAAO,CAAG,EAAA;AAC/CV,oBAAAA,oBAAAA,CAAqBT,GAAG,CAACW,QAASQ,CAAAA,OAAO,EAAE,EAAE,CAAA;AAC/C;AACAV,gBAAAA,oBAAAA,CAAqBQ,GAAG,CAACN,QAAAA,CAASQ,OAAO,CAAA,CAAGD,IAAI,CAACR,KAAAA,CAAAA;AACnD;AACF;AAEA,QAAA,IAAIU,SAAY,GAAA,KAAA;AAChB,QAAA,IAAIC,cAA0B,GAAA,IAAA;QAC9B,IAAI;YACF,IAAK,IAAIC,IAAI,CAAGA,EAAAA,CAAAA,GAAInB,SAASoB,aAAa,CAACnB,MAAM,EAAEkB,CAAK,EAAA,CAAA;AACtD,gBAAA,MAAME,IAAOrB,GAAAA,QAAAA,CAASoB,aAAa,CAACD,CAAE,CAAA;;gBAGtC,MAAMG,UAAAA,GAAanB,UAAWW,CAAAA,GAAG,CAACK,CAAAA,CAAAA;AAClC,gBAAA,IAAIG,UAAY,EAAA;oBACd,KAAK,MAAMf,SAASe,UAAY,CAAA;AAC9B,wBAAA,MAAMd,QAAWR,GAAAA,QAAAA,CAASS,SAAS,CAACK,GAAG,CAACP,KAAAA,CAAAA;AACxC,wBAAA,MAAMgB,IAAOf,GAAAA,QAAAA,CAASE,QAAQ,CAACa,IAAI;AACnC,wBAAA,MAAMC,IAAO,GAAA,IAAI,CAACC,YAAY,CAACF,IAAAA,CAAAA;AAC/B,wBAAA,MAAM3B,UAAU,IAAI,CAACR,UAAU,CAACsC,QAAQ,CAACH,IAAMC,EAAAA,IAAAA,CAAAA;AAC/C,wBAAA,IAAI,CAAC5C,kBAAkB,CAACiB,GAAG,CAACU,KAAOX,EAAAA,OAAAA,CAAAA;AACrC;AACF;;gBAGA,MAAM+B,sBAAAA,GAAyBtB,qBAAsBS,CAAAA,GAAG,CAACK,CAAAA,CAAAA;AACzD,gBAAA,IAAIQ,sBAAwB,EAAA;oBAC1B,KAAK,MAAMpB,SAASoB,sBAAwB,CAAA;AAC1C,wBAAA,MAAMnB,QAAWR,GAAAA,QAAAA,CAASS,SAAS,CAACK,GAAG,CAACP,KAAAA,CAAAA;AACxC,wBAAA,MAAMgB,IAAOf,GAAAA,QAAAA,CAASE,QAAQ,CAACa,IAAI;wBACnC,MAAMK,WAAAA,GAAc,IAAI,CAACC,kBAAkB,CAAC,IAAI,CAACC,uBAAuB,CAACP,IAAO,CAAA,EAAA,KAAA,CAAA;AAChF,wBAAA,IAAI,CAAC1C,sBAAsB,CAACgB,GAAG,CAACU,KAAOqB,EAAAA,WAAAA,CAAAA;AACzC;AACF;;;AAIA,gBAAA,IAAIG,SAAqB,GAAA,IAAA;gBACzB,IAAI;AACF,oBAAA,IAAIV,IAAKW,CAAAA,SAAS,CAAC/B,MAAM,GAAG,CAAG,EAAA;AAC7B,wBAAA,MAAMgC,WAAc,GAAA,IAAI,CAACC,kBAAkB,CAACb,IAAAA,CAAAA;AAC5C,wBAAA,MAAMc,GAAM,GAAA,IAAI,CAACC,cAAc,CAACH,WAAAA,CAAAA;AAChC,wBAAA,KAAK,MAAMI,OAAAA,IAAWhB,IAAKW,CAAAA,SAAS,CAAE;4BACpC,IAAI;AACDK,gCAAAA,OAAAA,CAAQC,SAAS,CAA0BH,GAAKd,EAAAA,IAAAA,CAAKkB,IAAI,CAAA;AAC5D,6BAAA,CAAE,OAAOC,CAAG,EAAA;gCACV,MAAM,IAAI,CAACC,iBAAiB,CAACpB,KAAKqB,IAAI,EAAEL,OAAQK,CAAAA,IAAI,EAAEF,CAAAA,CAAAA;AACxD;AACF;qBACK,MAAA,IAAInB,IAAKiB,CAAAA,SAAS,EAAE;AACzB,wBAAA,MAAML,WAAc,GAAA,IAAI,CAACC,kBAAkB,CAACb,IAAAA,CAAAA;AAC5C,wBAAA,MAAMc,GAAM,GAAA,IAAI,CAACC,cAAc,CAACH,WAAAA,CAAAA;AAC/BZ,wBAAAA,IAAAA,CAAKiB,SAAS,CAA0BH,GAAKd,EAAAA,IAAAA,CAAKkB,IAAI,CAAA;AACzD;AACF,iBAAA,CAAE,OAAOC,CAAG,EAAA;oBACVT,SAAYS,GAAAA,CAAAA;AACd;AAEA,gBAAA,IAAIG,YAAwB,GAAA,IAAA;gBAC5B,MAAMC,qBAAAA,GAAwBtC,oBAAqBQ,CAAAA,GAAG,CAACK,CAAAA,CAAAA;AACvD,gBAAA,IAAIyB,qBAAuB,EAAA;oBACzB,KAAK,MAAMrC,SAASqC,qBAAuB,CAAA;AACzC,wBAAA,MAAMhB,cAAc,IAAI,CAAC/C,sBAAsB,CAACiC,GAAG,CAACP,KAAAA,CAAAA;AACpD,wBAAA,IAAIqB,gBAAgBiB,SAAW,EAAA;4BAC7B,IAAI;gCACF,IAAI,CAACC,mBAAmB,CAAClB,WAAAA,CAAAA;AACzB,gCAAA,IAAI,CAAC/C,sBAAsB,CAACkE,MAAM,CAACxC,KAAAA,CAAAA;AACrC,6BAAA,CAAE,OAAOiC,CAAG,EAAA;gCACVG,YAAiBH,KAAAA,CAAAA;AACnB;AACF;AACF;AACF;;gBAEA,MAAMQ,SAAAA,GAAY5C,SAAUU,CAAAA,GAAG,CAACK,CAAAA,CAAAA;AAChC,gBAAA,IAAI6B,SAAW,EAAA;oBACb,KAAK,MAAMzC,SAASyC,SAAW,CAAA;AAC7B,wBAAA,MAAMpD,UAAU,IAAI,CAAChB,kBAAkB,CAACkC,GAAG,CAACP,KAAAA,CAAAA;AAC5C,wBAAA,IAAIX,YAAYiD,SAAW,EAAA;4BACzB,IAAI;AACF,gCAAA,IAAI,CAACzD,UAAU,CAAC6D,OAAO,CAACrD,OAAAA,CAAAA;AACxB,gCAAA,IAAI,CAAChB,kBAAkB,CAACmE,MAAM,CAACxC,KAAAA,CAAAA;AACjC,6BAAA,CAAE,OAAOiC,CAAG,EAAA;gCACVG,YAAiBH,KAAAA,CAAAA;AACnB;AACF;AACF;AACF;AACA,gBAAA,IAAIT,SAAW,EAAA;oBACb,MAAMA,SAAAA;AACR;AACA,gBAAA,IAAIY,YAAc,EAAA;oBAChB,MAAMA,YAAAA;AACR;AACF;YACA1B,SAAY,GAAA,IAAA;AACd,SAAA,CAAE,OAAOuB,CAAG,EAAA;YACVtB,cAAiBsB,GAAAA,CAAAA;SACT,QAAA;AACR,YAAA,IAAIU,YAAwB,GAAA,IAAA;YAC5B,IAAI;AACF,gBAAA,IAAI,CAACC,oBAAoB,EAAA;AAC3B,aAAA,CAAE,OAAOX,CAAG,EAAA;gBACVU,YAAeV,GAAAA,CAAAA;aACP,QAAA;AACR,gBAAA,IAAI,CAACvB,SAAW,EAAA;oBACd,IAAI;AACF,wBAAA,IAAI,CAACmC,KAAK,EAAA;AACZ,qBAAA,CAAE,OAAOZ,CAAG,EAAA;wBACVU,YAAiBV,KAAAA,CAAAA;AACnB;AACF;AACF;AACA,YAAA,IAAItB,cAAgB,EAAA;gBAClB,MAAMA,cAAAA;AACR;AACA,YAAA,IAAIgC,YAAc,EAAA;gBAChB,MAAMA,YAAAA;AACR;AACF;AACF;AAEA;;;AAGC,MACDE,KAAc,GAAA;AACZ,QAAA,IAAI,CAACD,oBAAoB,EAAA;;AAEzB,QAAA,KAAK,MAAMvB,WAAe,IAAA,IAAI,CAAC/C,sBAAsB,CAACwE,MAAM,EAAI,CAAA;YAC9D,IAAI,CAACP,mBAAmB,CAAClB,WAAAA,CAAAA;AAC3B;QACA,IAAI,CAAC/C,sBAAsB,CAACyE,KAAK,EAAA;AACjC,QAAA,KAAK,MAAM1D,OAAW,IAAA,IAAI,CAAChB,kBAAkB,CAACyE,MAAM,EAAI,CAAA;AACtD,YAAA,IAAI,CAACjE,UAAU,CAAC6D,OAAO,CAACrD,OAAAA,CAAAA;AAC1B;QACA,IAAI,CAAChB,kBAAkB,CAAC0E,KAAK,EAAA;QAC7B,IAAI,CAAC5E,iBAAiB,CAAC4E,KAAK,EAAA;QAC5B,IAAI,CAACxE,uBAAuB,CAACwE,KAAK,EAAA;QAClC,IAAI,CAACvE,yBAAyB,CAACuE,KAAK,EAAA;AACtC;;AAIA,qBACQ7B,YAAaF,CAAAA,IAAmB,EAAkB;QACxD,MAAMgC,IAAAA,GAAOhC,IAAKiC,CAAAA,QAAQ,IAAI,qBAAA;AAC9B,QAAA,IAAID,SAAS,UAAY,EAAA;YACvB,OAAO;gBACL/D,KAAO+B,EAAAA,IAAAA,CAAK/B,KAAK,IAAI,CAAA;gBACrBC,MAAQ8B,EAAAA,IAAAA,CAAK9B,MAAM,IAAI;AACzB,aAAA;AACF;;QAEA,MAAMgE,MAAAA,GAASlC,IAAK/B,CAAAA,KAAK,IAAI,GAAA;QAC7B,MAAMkE,MAAAA,GAASnC,IAAK9B,CAAAA,MAAM,IAAI,GAAA;QAC9B,OAAO;YACLD,KAAOmE,EAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAKE,KAAK,CAAC,IAAI,CAACxE,gBAAgB,GAAGoE,MAAAA,CAAAA,CAAAA;YACtDhE,MAAQkE,EAAAA,IAAAA,CAAKC,GAAG,CAAC,CAAGD,EAAAA,IAAAA,CAAKE,KAAK,CAAC,IAAI,CAACvE,iBAAiB,GAAGoE,MAAAA,CAAAA;AAC1D,SAAA;AACF;AAEA,qBACQxD,8BAA+BF,CAAAA,QAA6B,EAAQ;QAC1E,IAAI,CAAClB,uBAAuB,CAACwE,KAAK,EAAA;QAClC,IAAI,CAACvE,yBAAyB,CAACuE,KAAK,EAAA;AACpC,QAAA,MAAMQ,oBAAoB,IAAInF,GAAAA,EAAAA;AAC9B,QAAA,KAAK,MAAM6B,QAAYR,IAAAA,QAAAA,CAASS,SAAS,CAAC4C,MAAM,EAAI,CAAA;YAClD,MAAM3C,QAAAA,GAAWF,SAASE,QAAQ;YAClC,IAAIA,QAAAA,CAASC,IAAI,KAAK,UAAY,EAAA;AAChC,gBAAA;AACF;AACA,YAAA,MAAMf,UACJ,IAAI,CAAClB,iBAAiB,CAACoC,GAAG,CAACJ,QAAAA,CAASqD,EAAE,CAAA,IAAK,IAAI,CAACrF,iBAAiB,CAACoC,GAAG,CAACJ,SAASsD,UAAU,CAAA;AAC3F,YAAA,IAAIpE,YAAYiD,SAAW,EAAA;AACzBiB,gBAAAA,iBAAAA,CAAkBjE,GAAG,CAACa,QAASsD,CAAAA,UAAU,EAAEpE,OAAAA,CAAAA;AAC7C;AACF;AACA,QAAA,KAAK,MAAMY,QAAYR,IAAAA,QAAAA,CAASS,SAAS,CAAC4C,MAAM,EAAI,CAAA;YAClD,MAAM3C,QAAAA,GAAWF,SAASE,QAAQ;YAClC,IAAIA,QAAAA,CAASC,IAAI,KAAK,UAAY,EAAA;AAChC,gBAAA;AACF;YACA,IAAI,CAAC7B,uBAAuB,CAACe,GAAG,CAACa,QAASqD,CAAAA,EAAE,EAAErD,QAAAA,CAASsD,UAAU,CAAA;AACjE,YAAA,MAAMpE,OAAUkE,GAAAA,iBAAAA,CAAkBhD,GAAG,CAACJ,SAASsD,UAAU,CAAA;AACzD,YAAA,IAAIpE,YAAYiD,SAAW,EAAA;AACzB,gBAAA,IAAI,CAAC9D,yBAAyB,CAACc,GAAG,CAACa,QAAAA,CAASqD,EAAE,EAAEnE,OAAAA,CAAAA;AAChD,gBAAA,IAAI,CAACb,yBAAyB,CAACc,GAAG,CAACa,QAAAA,CAASsD,UAAU,EAAEpE,OAAAA,CAAAA;AAC1D;AACF;AACF;qBAGA,oBAAqC,GAAA;AACnC,QAAA,IAAIqE,KAAiB,GAAA,IAAA;AACrB,QAAA,MAAO,IAAI,CAACjF,iBAAiB,CAACiB,MAAM,GAAG,CAAG,CAAA;AACxC,YAAA,MAAMiE,QAAW,GAAA,IAAI,CAAClF,iBAAiB,CAACmF,GAAG,EAAA;YAC3C,IAAI;AACFD,gBAAAA,QAAAA,EAAAA;AACF,aAAA,CAAE,OAAO1B,CAAG,EAAA;gBACVyB,KAAUzB,KAAAA,CAAAA;AACZ;AACF;AACA,QAAA,IAAIyB,KAAO,EAAA;YACT,MAAMA,KAAAA;AACR;AACF;AAEA,qBACA,kBAAQpC,CAAmBN,IAAuB,EAAE6C,WAAAA,GAAc,IAAI,EAAgB;AACpF,QAAA,IAAI,CAAC,IAAI,CAAChF,UAAU,CAACiF,mBAAmB,IAAI,CAAC,IAAI,CAACjF,UAAU,CAACkF,kBAAkB,EAAE;AAC/E,YAAA,MAAM,IAAIC,KAAM,CAAA,iFAAA,CAAA;AAClB;AACA,QAAA,MAAM3C,cAAc,IAAI,CAACxC,UAAU,CAACiF,mBAAmB,CAAC9C,IAAAA,CAAAA;AACxD,QAAA,IAAI6C,WAAa,EAAA;AACf,YAAA,IAAI,CAACpF,iBAAiB,CAAC+B,IAAI,CAAC,IAAA;AAC1B,gBAAA,IAAI,CAAC3B,UAAU,CAACkF,kBAAkB,CAAE1C,WAAAA,CAAAA;AACtC,aAAA,CAAA;AACF;QACA,OAAOA,WAAAA;AACT;AAEA,qBACQkB,mBAAoBlB,CAAAA,WAAyB,EAAQ;AAC3D,QAAA,IAAI,CAAC,IAAI,CAACxC,UAAU,CAACkF,kBAAkB,EAAE;AACvC,YAAA,MAAM,IAAIC,KAAM,CAAA,8EAAA,CAAA;AAClB;AACA,QAAA,IAAI,CAACnF,UAAU,CAACkF,kBAAkB,CAAC1C,WAAAA,CAAAA;AACrC;AAEA,qBACA,uBAAQE,CACNP,IAAuB,EACvBU,WAA+B,EACZ;AACnB,QAAA,MAAMuC,oBAAoB,CAACC,UAAAA,GAAAA;AACzB,YAAA,IAAIA,sBAAsBC,QAAU,EAAA;AAClC,gBAAA,IAAIzC,WAAa,EAAA;AACf,oBAAA,IAAI,CAAC0C,qBAAqB,CAAC1C,WAAAA,EAAawC,UAAY,EAAA,SAAA,CAAA;AACtD;gBACA,OAAO,IAAI,CAACG,gBAAgB,CAACH,UAAAA,CAAAA;AAC/B;YACA,OAAOA,UAAAA;AACT,SAAA;AACA,QAAA,MAAMI,SAASC,KAAMC,CAAAA,OAAO,CAACxD,IAAKyD,CAAAA,gBAAgB,IAC9CzD,IAAKyD,CAAAA,gBAAgB,CAACC,GAAG,CAACT,qBAC1BjD,IAAKyD,CAAAA,gBAAgB,GACnBR,iBAAkBjD,CAAAA,IAAAA,CAAKyD,gBAAgB,CACvC,GAAA,IAAA;QACN,OAAO;AACL,YAAA,GAAGzD,IAAI;YACPyD,gBAAkBH,EAAAA,MAAAA;YAClBK,eAAiBV,EAAAA,iBAAAA,CAAkBjD,KAAK2D,eAAe;AACzD,SAAA;AACF;AAEA,qBACQN,gBAAiBjF,CAAAA,MAAgB,EAAY;QACnD,MAAMwF,QAAAA,GAAW,IAAI,CAACzG,iBAAiB,CAACoC,GAAG,CAACnB,OAAOG,GAAG,CAAA;AACtD,QAAA,IAAIqF,aAAatC,SAAW,EAAA;YAC1B,OAAOsC,QAAAA;AACT;QACA,MAAMC,gBAAAA,GAAmB,IAAI,CAACrG,yBAAyB,CAAC+B,GAAG,CAACnB,OAAOG,GAAG,CAAA;AACtE,QAAA,IAAIsF,qBAAqBvC,SAAW,EAAA;YAClC,OAAOuC,gBAAAA;AACT;QACA,MAAMC,aAAAA,GAAgB,IAAI,CAACvG,uBAAuB,CAACgC,GAAG,CAACnB,OAAOG,GAAG,CAAA;AACjE,QAAA,IAAIuF,kBAAkBxC,SAAW,EAAA;AAC/B,YAAA,MAAMyC,OACJ,GAAA,IAAI,CAAC5G,iBAAiB,CAACoC,GAAG,CAACuE,aAAAA,CAAAA,IAAkB,IAAI,CAACtG,yBAAyB,CAAC+B,GAAG,CAACuE,aAAAA,CAAAA;AAClF,YAAA,IAAIC,YAAYzC,SAAW,EAAA;gBACzB,OAAOyC,OAAAA;AACT;AACF;QACA,MAAMC,SAAAA,GAAY,IAAI,CAAC3G,kBAAkB,CAACkC,GAAG,CAACnB,OAAOG,GAAG,CAAA;AACxD,QAAA,IAAIyF,cAAc1C,SAAW,EAAA;YAC3B,OAAO0C,SAAAA;AACT;AACA,QAAA,MAAM,IAAIhB,KACR,CAAA,CAAC,8CAA8C,EAAE5E,MAAAA,CAAO+C,IAAI,CAAC,MAAM,EAAE/C,MAAAA,CAAOG,GAAG,CAAC,GAAG,CAAC,GAClF,CAAC,2DAA2D,CAAC,CAAA;AAEnE;AAEA,qBACQoC,kBAAmBb,CAAAA,IAAY,EAAqB;AAC1D,QAAA,MAAMmE,gBAAgB,IAAIC,GAAAA,EAAAA;AAC1B,QAAA,MAAMC,aAAa,IAAID,GAAAA,EAAAA;AACvB,QAAA,MAAME,iBAAiB,IAAIF,GAAAA,EAAAA;AAC3B,QAAA,KAAK,MAAM/E,QAAAA,IAAYW,IAAKuE,CAAAA,KAAK,CAAE;YACjCJ,aAAcK,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAC7B,YAAA,IAAIrD,SAASC,IAAI,KAAK,eAAeD,QAASC,CAAAA,IAAI,KAAK,UAAY,EAAA;gBACjE+E,UAAWG,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAC5B,aAAA,MAAO,IAAIrD,QAAAA,CAASC,IAAI,KAAK,aAAe,EAAA;gBAC1CgF,cAAeE,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAChC;AACF;AACA,QAAA,KAAK,MAAMrD,QAAAA,IAAYW,IAAKyE,CAAAA,MAAM,CAAE;YAClCN,aAAcK,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAC7B,YAAA,IAAIrD,SAASC,IAAI,KAAK,eAAeD,QAASC,CAAAA,IAAI,KAAK,UAAY,EAAA;gBACjE+E,UAAWG,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAC5B,aAAA,MAAO,IAAIrD,QAAAA,CAASC,IAAI,KAAK,aAAe,EAAA;gBAC1CgF,cAAeE,CAAAA,GAAG,CAACnF,QAAAA,CAASqD,EAAE,CAAA;AAChC;AACF;QACA,OAAO;AACLgC,YAAAA,QAAAA,EAAU1E,KAAKqB,IAAI;AACnB8C,YAAAA,aAAAA;AACAE,YAAAA,UAAAA;AACAC,YAAAA;AACF,SAAA;AACF;qBAGA,qBACE1D,CAAAA,WAA8B,EAC9BtC,MAAgB,EAChBqG,MAAiC,EAC3B;QACN,IAAI,CAAC/D,YAAYuD,aAAa,CAAC5E,GAAG,CAACjB,MAAAA,CAAOG,GAAG,CAAG,EAAA;YAC9C,MAAM,IAAIyE,MACR,CAAC,2BAA2B,EAAEtC,WAAY8D,CAAAA,QAAQ,CAAC,kBAAkB,EAAEC,OAAO,EAAE,EAAErG,OAAO+C,IAAI,CAAC,EAAE,CAAC,GAC/F,CAAC,0CAA0C,CAAC,CAAA;AAElD;QACA,IAAIsD,MAAAA,KAAW,SAAa,IAAA,CAAC/D,WAAYyD,CAAAA,UAAU,CAAC9E,GAAG,CAACjB,MAAOG,CAAAA,GAAG,CAAG,EAAA;AACnE,YAAA,MAAM,IAAIyE,KACR,CAAA,CAAC,2BAA2B,EAAEtC,WAAAA,CAAY8D,QAAQ,CAAC,mBAAmB,EAAEpG,MAAAA,CAAO+C,IAAI,CAAC,gBAAgB,CAAC,GACnG,CAAC,iCAAiC,CAAC,CAAA;AAEzC;QACA,IAAIsD,MAAAA,KAAW,aAAiB,IAAA,CAAC/D,WAAY0D,CAAAA,cAAc,CAAC/E,GAAG,CAACjB,MAAOG,CAAAA,GAAG,CAAG,EAAA;AAC3E,YAAA,MAAM,IAAIyE,KACR,CAAA,CAAC,2BAA2B,EAAEtC,WAAAA,CAAY8D,QAAQ,CAAC,mBAAmB,EAAEpG,MAAAA,CAAO+C,IAAI,CAAC,oBAAoB,CAAC,GACvG,CAAC,qCAAqC,CAAC,CAAA;AAE7C;AACF;qBAGA,iBAA0BqD,CAAAA,QAAgB,EAAEE,WAAmB,EAAEhC,KAAc,EAAS;AACtF,QAAA,MAAMiC,UAAUjC,KAAiBM,YAAAA,KAAAA,GAAQN,KAAMiC,CAAAA,OAAO,GAAGC,MAAOlC,CAAAA,KAAAA,CAAAA;AAChE,QAAA,MAAMmC,OAAU,GAAA,IAAI7B,KAClB,CAAA,CAAC,2BAA2B,EAAEwB,QAAS,CAAA,WAAW,EAAEE,WAAAA,CAAY,UAAU,EAAEC,OAAS,CAAA,CAAA,CAAA;AAEtFE,QAAAA,OAAAA,CAAwCC,KAAK,GAAGpC,KAAAA;QACjD,OAAOmC,OAAAA;AACT;AAEA,qBACQhE,cAAeH,CAAAA,WAA8B,EAAoB;AACvE,QAAA,MAAMqE,OAAO,IAAI;QACjB,OAAO;AACLC,YAAAA,UAAAA,CAAAA,CAAc5G,MAAgB,EAAA;gBAC5B2G,IAAK3B,CAAAA,qBAAqB,CAAC1C,WAAAA,EAAatC,MAAQ,EAAA,SAAA,CAAA;gBAChD,OAAO2G,IAAAA,CAAK1B,gBAAgB,CAACjF,MAAAA,CAAAA;AAC/B,aAAA;AACA6G,YAAAA,cAAAA,CAAAA,CAAuC7G,MAAgB,EAAA;gBACrD2G,IAAK3B,CAAAA,qBAAqB,CAAC1C,WAAAA,EAAatC,MAAQ,EAAA,aAAA,CAAA;AAChD,gBAAA,MAAMiC,cAAc0E,IAAKzH,CAAAA,sBAAsB,CAACiC,GAAG,CAACnB,OAAOG,GAAG,CAAA;AAC9D,gBAAA,IAAI8B,gBAAgBiB,SAAW,EAAA;oBAC7B,OAAOjB,WAAAA;AACT;AACA,gBAAA,MAAM,IAAI2C,KACR,CAAA,CAAC,iDAAiD,EAAE5E,MAAAA,CAAO+C,IAAI,CAAC,MAAM,EAAE/C,MAAAA,CAAOG,GAAG,CAAC,GAAG,CAAC,GACrF,CAAC,2DAA2D,CAAC,CAAA;AAEnE,aAAA;AACA2G,YAAAA,iBAAAA,CAAAA,CAA0ClF,IAAuB,EAAA;AAC/D,gBAAA,OAAO+E,KAAKzE,kBAAkB,CAC5ByE,IAAKxE,CAAAA,uBAAuB,CAACP,IAAMU,EAAAA,WAAAA,CAAAA,CAAAA;AAEvC,aAAA;AACAyE,YAAAA,YAAAA,CAAAA,CAAaxC,QAAoB,EAAA;gBAC/BoC,IAAKtH,CAAAA,iBAAiB,CAAC+B,IAAI,CAACmD,QAAAA,CAAAA;AAC9B;AACF,SAAA;AACF;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"executor.js","sources":["../../../src/render/rendergraph/executor.ts"],"sourcesContent":["import type {\r\n CompiledRenderGraph,\r\n RenderGraphExecutorOptions,\r\n RGProfileResult,\r\n RGProfileScopeResult,\r\n RGProfileScopeType,\r\n RGProfilingOptions,\r\n RGTextureAllocator,\r\n RGTextureDesc,\r\n RGFramebufferDesc,\r\n RGResolvedSize,\r\n RGExecuteContext,\r\n RGExecuteFn,\r\n RGPass\r\n} from './types';\r\nimport { RGHandle } from './types';\r\nimport type { AbstractDevice, TimestampQueryResult, TimestampQueryStatus } from '@zephyr3d/device';\r\nimport { getDevice } from '../../app/api';\r\n\r\ninterface RGPassAccessScope {\r\n passName: string;\r\n accessibleIds: Set<number>;\r\n textureIds: Set<number>;\r\n framebufferIds: Set<number>;\r\n}\r\n\r\ntype RGResolvedProfilingOptions = Required<Omit<RGProfilingOptions, 'device'>> & {\r\n device?: AbstractDevice;\r\n};\r\n\r\ninterface RGProfileScopeInternal {\r\n result: RGProfileScopeResult;\r\n queryId: number;\r\n ended: boolean;\r\n}\r\n\r\ninterface RGProfileFrameInternal {\r\n serial: number;\r\n device: AbstractDevice | null;\r\n supported: boolean;\r\n result: RGProfileResult;\r\n root: RGProfileScopeInternal;\r\n scopes: RGProfileScopeInternal[];\r\n resolvePromise: Promise<RGProfileResult>;\r\n}\r\n\r\nconst DEFAULT_PROFILING_OPTIONS: RGResolvedProfilingOptions = {\r\n enabled: false,\r\n graph: true,\r\n pass: true,\r\n subpass: true,\r\n includePendingUploads: true,\r\n allowCrossFrame: false,\r\n maxPendingFrames: 3,\r\n label: 'RenderGraph'\r\n};\r\n\r\n/**\r\n * Executes a compiled render graph with automatic resource lifecycle management.\r\n *\r\n * The executor allocates transient textures before their first use and releases\r\n * them after their last use, using the provided {@link RGTextureAllocator}.\r\n *\r\n * Usage:\r\n * ```ts\r\n * const executor = new RenderGraphExecutor(myAllocator, backbufferWidth, backbufferHeight);\r\n * executor.setImportedTexture(backbufferHandle, actualBackbufferTexture);\r\n * executor.execute(compiledGraph);\r\n * ```\r\n *\r\n * @typeParam TTexture - The concrete texture type (e.g. `Texture2D`).\r\n * @public\r\n */\r\nexport class RenderGraphExecutor<TTexture = unknown, TFramebuffer = unknown> {\r\n private static _defaultProfilingOptions: boolean | RGProfilingOptions = false;\r\n private static _latestProfileResult: RGProfileResult | null = null;\r\n private static _latestPendingProfileFrame: RGProfileFrameInternal | null = null;\r\n private static _latestResolvedProfileSerial = 0;\r\n private static _nextProfileSerial = 0;\r\n\r\n /** @internal */\r\n private _allocator: RGTextureAllocator<TTexture, TFramebuffer>;\r\n /** @internal */\r\n private _backbufferWidth: number;\r\n /** @internal */\r\n private _backbufferHeight: number;\r\n /** @internal */\r\n private _importedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _allocatedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _allocatedFramebuffers: Map<number, TFramebuffer> = new Map();\r\n /** @internal */\r\n private _importedTextureAliases: Map<number, number> = new Map();\r\n /** @internal */\r\n private _resolvedImportedTextures: Map<number, TTexture> = new Map();\r\n /** @internal */\r\n private _cleanupCallbacks: Array<() => void> = [];\r\n /** @internal */\r\n private _profilingOptions: RGResolvedProfilingOptions;\r\n /** @internal */\r\n private _pendingProfileFrames: RGProfileFrameInternal[] = [];\r\n /** @internal */\r\n private _latestProfileResult: RGProfileResult | null = null;\r\n /** @internal */\r\n private _latestResolvedProfileSerial = 0;\r\n\r\n constructor(\r\n allocator: RGTextureAllocator<TTexture, TFramebuffer>,\r\n backbufferWidth: number,\r\n backbufferHeight: number,\r\n options?: RenderGraphExecutorOptions\r\n ) {\r\n this._allocator = allocator;\r\n this._backbufferWidth = backbufferWidth;\r\n this._backbufferHeight = backbufferHeight;\r\n this._profilingOptions = this._normalizeProfilingOptions(\r\n options?.profiling ?? RenderGraphExecutor._defaultProfilingOptions,\r\n options?.device\r\n );\r\n }\r\n\r\n /**\r\n * Set the default profiling options used by newly constructed render graph executors.\r\n */\r\n static setDefaultProfilingOptions(options: boolean | RGProfilingOptions): void {\r\n RenderGraphExecutor._defaultProfilingOptions = options;\r\n }\r\n\r\n /**\r\n * Get the latest resolved profile result from any render graph executor.\r\n */\r\n static getLatestProfileResult(): RGProfileResult | null {\r\n return RenderGraphExecutor._latestProfileResult;\r\n }\r\n\r\n /**\r\n * Resolve the latest pending render graph profile result from any executor.\r\n */\r\n static resolveProfileResult(): Promise<RGProfileResult | null> {\r\n return (\r\n RenderGraphExecutor._latestPendingProfileFrame?.resolvePromise ??\r\n Promise.resolve(RenderGraphExecutor._latestProfileResult)\r\n );\r\n }\r\n\r\n /**\r\n * Enable, disable, or update timestamp profiling for this executor.\r\n */\r\n setProfilingOptions(options: boolean | RGProfilingOptions): void {\r\n this._profilingOptions = this._normalizeProfilingOptions(options, this._profilingOptions.device);\r\n }\r\n\r\n /**\r\n * Get the latest resolved profile result produced by this executor.\r\n */\r\n getLatestProfileResult(): RGProfileResult | null {\r\n return this._latestProfileResult;\r\n }\r\n\r\n /**\r\n * Resolve the latest pending profile result produced by this executor.\r\n */\r\n resolveProfileResult(): Promise<RGProfileResult | null> {\r\n return (\r\n this._pendingProfileFrames[this._pendingProfileFrames.length - 1]?.resolvePromise ??\r\n Promise.resolve(this._latestProfileResult)\r\n );\r\n }\r\n\r\n /**\r\n * Update the backbuffer dimensions used for 'backbuffer-relative' sizing.\r\n */\r\n setBackbufferSize(width: number, height: number): void {\r\n this._backbufferWidth = width;\r\n this._backbufferHeight = height;\r\n }\r\n\r\n /**\r\n * Register an imported (external) texture so it can be resolved during execution.\r\n *\r\n * @param handle - The handle returned from {@link RenderGraph.importTexture}.\r\n * @param texture - The actual GPU texture object.\r\n */\r\n setImportedTexture(handle: RGHandle, texture: TTexture): void {\r\n this._importedTextures.set(handle._id, texture);\r\n }\r\n\r\n /**\r\n * Execute the compiled graph with full resource lifecycle management.\r\n *\r\n * For each pass in topological order:\r\n * 1. Allocate any transient resources whose lifetime begins at this pass\r\n * 2. Invoke the pass's execute callback with a context that resolves handles\r\n * 3. Release any transient resources whose lifetime ends at this pass\r\n *\r\n * @param compiled - The compiled graph from {@link RenderGraph.compile}.\r\n */\r\n execute(compiled: CompiledRenderGraph): void {\r\n this._cleanupCallbacks.length = 0;\r\n this._resolveImportedTextureAliases(compiled);\r\n const profileFrame = this._beginProfileFrame();\r\n\r\n // Build per-pass allocation and release schedules\r\n const allocateAt = new Map<number, number[]>(); // passIndex -> transient texture resourceIds to allocate\r\n const releaseAt = new Map<number, number[]>(); // passIndex -> transient texture resourceIds to release\r\n const allocateFramebufferAt = new Map<number, number[]>(); // passIndex -> framebuffer resourceIds to allocate\r\n const releaseFramebufferAt = new Map<number, number[]>(); // passIndex -> framebuffer resourceIds to release\r\n\r\n for (const [resId, lifetime] of compiled.lifetimes) {\r\n if (lifetime.resource.kind === 'transient') {\r\n if (!allocateAt.has(lifetime.firstUse)) {\r\n allocateAt.set(lifetime.firstUse, []);\r\n }\r\n allocateAt.get(lifetime.firstUse)!.push(resId);\r\n\r\n if (!releaseAt.has(lifetime.lastUse)) {\r\n releaseAt.set(lifetime.lastUse, []);\r\n }\r\n releaseAt.get(lifetime.lastUse)!.push(resId);\r\n } else if (lifetime.resource.kind === 'framebuffer') {\r\n if (!allocateFramebufferAt.has(lifetime.firstUse)) {\r\n allocateFramebufferAt.set(lifetime.firstUse, []);\r\n }\r\n allocateFramebufferAt.get(lifetime.firstUse)!.push(resId);\r\n\r\n if (!releaseFramebufferAt.has(lifetime.lastUse)) {\r\n releaseFramebufferAt.set(lifetime.lastUse, []);\r\n }\r\n releaseFramebufferAt.get(lifetime.lastUse)!.push(resId);\r\n }\r\n }\r\n\r\n let completed = false;\r\n let executionError: unknown = null;\r\n try {\r\n for (let i = 0; i < compiled.orderedPasses.length; i++) {\r\n const pass = compiled.orderedPasses[i];\r\n\r\n // Allocate resources that start at this pass\r\n const toAllocate = allocateAt.get(i);\r\n if (toAllocate) {\r\n for (const resId of toAllocate) {\r\n const lifetime = compiled.lifetimes.get(resId)!;\r\n const desc = lifetime.resource.desc as RGTextureDesc;\r\n const size = this._resolveSize(desc);\r\n const texture = this._allocator.allocate(desc, size);\r\n this._allocatedTextures.set(resId, texture);\r\n }\r\n }\r\n\r\n // Allocate framebuffer views after their texture attachments are available.\r\n const framebuffersToAllocate = allocateFramebufferAt.get(i);\r\n if (framebuffersToAllocate) {\r\n for (const resId of framebuffersToAllocate) {\r\n const lifetime = compiled.lifetimes.get(resId)!;\r\n const desc = lifetime.resource.desc as RGFramebufferDesc;\r\n const framebuffer = this._createFramebuffer(this._resolveFramebufferDesc(desc), false);\r\n this._allocatedFramebuffers.set(resId, framebuffer);\r\n }\r\n }\r\n\r\n // Execute the pass with exception safety for resource cleanup.\r\n // Release errors must not hide the original pass execution error.\r\n let passError: unknown = null;\r\n const passProfile = this._beginPassProfileScope(profileFrame, pass);\r\n try {\r\n if (pass.subpasses.length > 0) {\r\n const accessScope = this._createAccessScope(pass);\r\n const ctx = this._createContext(accessScope);\r\n for (const subpass of pass.subpasses) {\r\n const subpassProfile = this._beginSubpassProfileScope(\r\n profileFrame,\r\n passProfile,\r\n pass,\r\n subpass.name\r\n );\r\n try {\r\n (subpass.executeFn as RGExecuteFn<unknown>)(ctx, pass.data);\r\n } catch (e) {\r\n throw this._wrapSubpassError(pass.name, subpass.name, e);\r\n } finally {\r\n this._endProfileScope(profileFrame, subpassProfile);\r\n }\r\n }\r\n } else if (pass.executeFn) {\r\n const accessScope = this._createAccessScope(pass);\r\n const ctx = this._createContext(accessScope);\r\n (pass.executeFn as RGExecuteFn<unknown>)(ctx, pass.data);\r\n }\r\n } catch (e) {\r\n passError = e;\r\n } finally {\r\n this._endProfileScope(profileFrame, passProfile);\r\n }\r\n\r\n let releaseError: unknown = null;\r\n const framebuffersToRelease = releaseFramebufferAt.get(i);\r\n if (framebuffersToRelease) {\r\n for (const resId of framebuffersToRelease) {\r\n const framebuffer = this._allocatedFramebuffers.get(resId);\r\n if (framebuffer !== undefined) {\r\n try {\r\n this._releaseFramebuffer(framebuffer);\r\n this._allocatedFramebuffers.delete(resId);\r\n } catch (e) {\r\n releaseError ??= e;\r\n }\r\n }\r\n }\r\n }\r\n // Release resources that end at this pass (always runs even if pass throws)\r\n const toRelease = releaseAt.get(i);\r\n if (toRelease) {\r\n for (const resId of toRelease) {\r\n const texture = this._allocatedTextures.get(resId);\r\n if (texture !== undefined) {\r\n try {\r\n this._allocator.release(texture);\r\n this._allocatedTextures.delete(resId);\r\n } catch (e) {\r\n releaseError ??= e;\r\n }\r\n }\r\n }\r\n }\r\n if (passError) {\r\n throw passError;\r\n }\r\n if (releaseError) {\r\n throw releaseError;\r\n }\r\n }\r\n completed = true;\r\n } catch (e) {\r\n executionError = e;\r\n } finally {\r\n this._finishProfileFrame(profileFrame);\r\n let cleanupError: unknown = null;\r\n try {\r\n this._runCleanupCallbacks();\r\n } catch (e) {\r\n cleanupError = e;\r\n } finally {\r\n if (!completed) {\r\n try {\r\n this.reset();\r\n } catch (e) {\r\n cleanupError ??= e;\r\n }\r\n }\r\n }\r\n if (executionError) {\r\n throw executionError;\r\n }\r\n if (cleanupError) {\r\n throw cleanupError;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear imported texture registrations and any leftover allocated textures.\r\n * Call this after execution or when resetting for a new frame.\r\n */\r\n reset(): void {\r\n this._runCleanupCallbacks();\r\n // Release any textures that weren't released (shouldn't happen in normal flow)\r\n for (const framebuffer of this._allocatedFramebuffers.values()) {\r\n this._releaseFramebuffer(framebuffer);\r\n }\r\n this._allocatedFramebuffers.clear();\r\n for (const texture of this._allocatedTextures.values()) {\r\n this._allocator.release(texture);\r\n }\r\n this._allocatedTextures.clear();\r\n this._importedTextures.clear();\r\n this._importedTextureAliases.clear();\r\n this._resolvedImportedTextures.clear();\r\n }\r\n\r\n // ─── Private ────────────────────────────────────────────────────────\r\n\r\n /** @internal */\r\n private _normalizeProfilingOptions(\r\n options: boolean | RGProfilingOptions | undefined,\r\n fallbackDevice?: AbstractDevice\r\n ): RGResolvedProfilingOptions {\r\n const source = typeof options === 'object' ? options : {};\r\n const enabled = typeof options === 'boolean' ? options : (source.enabled ?? true);\r\n return {\r\n enabled,\r\n graph: source.graph ?? DEFAULT_PROFILING_OPTIONS.graph,\r\n pass: source.pass ?? DEFAULT_PROFILING_OPTIONS.pass,\r\n subpass: source.subpass ?? DEFAULT_PROFILING_OPTIONS.subpass,\r\n includePendingUploads: source.includePendingUploads ?? DEFAULT_PROFILING_OPTIONS.includePendingUploads,\r\n allowCrossFrame: source.allowCrossFrame ?? DEFAULT_PROFILING_OPTIONS.allowCrossFrame,\r\n maxPendingFrames: Math.max(1, source.maxPendingFrames ?? DEFAULT_PROFILING_OPTIONS.maxPendingFrames),\r\n label: source.label ?? DEFAULT_PROFILING_OPTIONS.label,\r\n device: source.device ?? fallbackDevice\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _getProfilingDevice(): AbstractDevice | null {\r\n if (this._profilingOptions.device) {\r\n return this._profilingOptions.device;\r\n }\r\n try {\r\n return getDevice();\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _beginProfileFrame(): RGProfileFrameInternal | null {\r\n if (!this._profilingOptions.enabled) {\r\n return null;\r\n }\r\n const device = this._getProfilingDevice();\r\n const supported = !!device?.getDeviceCaps().miscCaps.supportTimestampQuery;\r\n const rootResult: RGProfileScopeResult = {\r\n name: this._profilingOptions.label,\r\n type: 'graph',\r\n queryId: 0,\r\n durationMs: 0,\r\n status: supported ? 'resolved' : 'unsupported',\r\n children: [],\r\n message: supported ? undefined : 'GPU timestamp queries are not supported'\r\n };\r\n const result: RGProfileResult = {\r\n frameId: device?.frameInfo.frameCounter ?? -1,\r\n status: rootResult.status,\r\n graph: rootResult,\r\n passes: rootResult.children\r\n };\r\n const root: RGProfileScopeInternal = {\r\n result: rootResult,\r\n queryId: 0,\r\n ended: false\r\n };\r\n const frame: RGProfileFrameInternal = {\r\n serial: ++RenderGraphExecutor._nextProfileSerial,\r\n device,\r\n supported,\r\n result,\r\n root,\r\n scopes: [],\r\n resolvePromise: Promise.resolve(result)\r\n };\r\n if (this._profilingOptions.graph) {\r\n this._beginTimestampScope(frame, root, this._profilingOptions.label);\r\n }\r\n return frame;\r\n }\r\n\r\n /** @internal */\r\n private _beginPassProfileScope(\r\n frame: RGProfileFrameInternal | null,\r\n pass: RGPass\r\n ): RGProfileScopeInternal | null {\r\n if (!frame || (!this._profilingOptions.pass && !this._profilingOptions.subpass)) {\r\n return null;\r\n }\r\n return this._beginProfileScope(frame, frame.root, 'pass', pass.name, this._profilingOptions.pass);\r\n }\r\n\r\n /** @internal */\r\n private _beginSubpassProfileScope(\r\n frame: RGProfileFrameInternal | null,\r\n passScope: RGProfileScopeInternal | null,\r\n pass: RGPass,\r\n subpassName: string\r\n ): RGProfileScopeInternal | null {\r\n if (!frame || !this._profilingOptions.subpass) {\r\n return null;\r\n }\r\n const parent = passScope ?? frame.root;\r\n return this._beginProfileScope(\r\n frame,\r\n parent,\r\n 'subpass',\r\n subpassName,\r\n true,\r\n `${pass.name}/${subpassName}`\r\n );\r\n }\r\n\r\n /** @internal */\r\n private _beginProfileScope(\r\n frame: RGProfileFrameInternal,\r\n parent: RGProfileScopeInternal,\r\n type: RGProfileScopeType,\r\n name: string,\r\n queryEnabled: boolean,\r\n queryLabel?: string\r\n ): RGProfileScopeInternal {\r\n const status =\r\n frame.supported && !queryEnabled ? 'resolved' : frame.supported ? 'pending' : 'unsupported';\r\n const result: RGProfileScopeResult = {\r\n name,\r\n type,\r\n queryId: 0,\r\n durationMs: 0,\r\n status,\r\n children: [],\r\n message: frame.supported ? undefined : 'GPU timestamp queries are not supported'\r\n };\r\n parent.result.children.push(result);\r\n const scope: RGProfileScopeInternal = {\r\n result,\r\n queryId: 0,\r\n ended: false\r\n };\r\n if (queryEnabled) {\r\n this._beginTimestampScope(frame, scope, queryLabel ?? name);\r\n }\r\n return scope;\r\n }\r\n\r\n /** @internal */\r\n private _beginTimestampScope(\r\n frame: RGProfileFrameInternal,\r\n scope: RGProfileScopeInternal,\r\n label: string\r\n ): void {\r\n if (!frame.supported || !frame.device) {\r\n scope.result.status = 'unsupported';\r\n scope.result.message = 'GPU timestamp queries are not supported';\r\n return;\r\n }\r\n const queryId = frame.device.beginTimestampQuery(label, {\r\n includePendingUploads: this._profilingOptions.includePendingUploads,\r\n allowCrossFrame: this._profilingOptions.allowCrossFrame\r\n });\r\n scope.queryId = queryId;\r\n scope.result.queryId = queryId;\r\n if (queryId > 0) {\r\n scope.result.status = 'pending';\r\n frame.scopes.push(scope);\r\n } else {\r\n scope.result.status = 'unsupported';\r\n scope.result.message = 'GPU timestamp query was not started';\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _endProfileScope(frame: RGProfileFrameInternal | null, scope: RGProfileScopeInternal | null): void {\r\n if (!frame || !frame.device || !scope || scope.ended) {\r\n return;\r\n }\r\n scope.ended = true;\r\n if (scope.queryId > 0) {\r\n frame.device.endTimestampQuery(scope.queryId);\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _finishProfileFrame(frame: RGProfileFrameInternal | null): void {\r\n if (!frame) {\r\n return;\r\n }\r\n this._endProfileScope(frame, frame.root);\r\n if (frame.scopes.length === 0 || !frame.device) {\r\n frame.result.status = this._aggregateProfileStatus(frame.result.graph);\r\n this._publishProfileResult(frame);\r\n return;\r\n }\r\n frame.resolvePromise = Promise.all(\r\n frame.scopes.map((scope) => frame.device!.resolveTimestampQuery(scope.queryId))\r\n )\r\n .then((results) => {\r\n for (let i = 0; i < results.length; i++) {\r\n this._applyTimestampResult(frame.scopes[i], results[i]);\r\n }\r\n frame.result.status = this._aggregateProfileStatus(frame.result.graph);\r\n this._publishProfileResult(frame);\r\n return frame.result;\r\n })\r\n .catch((err) => {\r\n const message = err instanceof Error ? err.message : String(err);\r\n for (const scope of frame.scopes) {\r\n scope.result.status = 'failed';\r\n scope.result.message = message;\r\n }\r\n frame.result.status = 'failed';\r\n this._publishProfileResult(frame);\r\n return frame.result;\r\n });\r\n this._trackPendingProfileFrame(frame);\r\n }\r\n\r\n /** @internal */\r\n private _trackPendingProfileFrame(frame: RGProfileFrameInternal): void {\r\n this._pendingProfileFrames.push(frame);\r\n while (this._pendingProfileFrames.length > this._profilingOptions.maxPendingFrames) {\r\n this._pendingProfileFrames.shift();\r\n }\r\n RenderGraphExecutor._latestPendingProfileFrame = frame;\r\n }\r\n\r\n /** @internal */\r\n private _publishProfileResult(frame: RGProfileFrameInternal): void {\r\n this._pendingProfileFrames = this._pendingProfileFrames.filter((pending) => pending !== frame);\r\n if (frame.serial >= this._latestResolvedProfileSerial) {\r\n this._latestResolvedProfileSerial = frame.serial;\r\n this._latestProfileResult = frame.result;\r\n }\r\n if (frame.serial >= RenderGraphExecutor._latestResolvedProfileSerial) {\r\n RenderGraphExecutor._latestResolvedProfileSerial = frame.serial;\r\n RenderGraphExecutor._latestProfileResult = frame.result;\r\n }\r\n if (RenderGraphExecutor._latestPendingProfileFrame === frame) {\r\n RenderGraphExecutor._latestPendingProfileFrame = null;\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _applyTimestampResult(scope: RGProfileScopeInternal, result: TimestampQueryResult): void {\r\n scope.result.queryId = result.id;\r\n scope.result.durationMs = result.durationMs;\r\n scope.result.status = result.status;\r\n scope.result.message = result.message;\r\n }\r\n\r\n /** @internal */\r\n private _aggregateProfileStatus(scope: RGProfileScopeResult): TimestampQueryStatus {\r\n const statuses: TimestampQueryStatus[] = [];\r\n const collect = (node: RGProfileScopeResult) => {\r\n statuses.push(node.status);\r\n for (const child of node.children) {\r\n collect(child);\r\n }\r\n };\r\n collect(scope);\r\n for (const status of ['failed', 'invalid', 'exhausted', 'pending', 'auto-closed'] as const) {\r\n if (statuses.includes(status)) {\r\n return status;\r\n }\r\n }\r\n if (statuses.includes('unsupported')) {\r\n return 'unsupported';\r\n }\r\n return 'resolved';\r\n }\r\n\r\n /** @internal */\r\n private _resolveSize(desc: RGTextureDesc): RGResolvedSize {\r\n const mode = desc.sizeMode ?? 'backbuffer-relative';\r\n if (mode === 'absolute') {\r\n return {\r\n width: desc.width ?? 1,\r\n height: desc.height ?? 1\r\n };\r\n }\r\n // backbuffer-relative: width/height are scale factors (default 1.0)\r\n const scaleX = desc.width ?? 1.0;\r\n const scaleY = desc.height ?? 1.0;\r\n return {\r\n width: Math.max(1, Math.floor(this._backbufferWidth * scaleX)),\r\n height: Math.max(1, Math.floor(this._backbufferHeight * scaleY))\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _resolveImportedTextureAliases(compiled: CompiledRenderGraph): void {\r\n this._importedTextureAliases.clear();\r\n this._resolvedImportedTextures.clear();\r\n const physicalToTexture = new Map<number, TTexture>();\r\n for (const lifetime of compiled.lifetimes.values()) {\r\n const resource = lifetime.resource;\r\n if (resource.kind !== 'imported') {\r\n continue;\r\n }\r\n const texture =\r\n this._importedTextures.get(resource.id) ?? this._importedTextures.get(resource.physicalId);\r\n if (texture !== undefined) {\r\n physicalToTexture.set(resource.physicalId, texture);\r\n }\r\n }\r\n for (const lifetime of compiled.lifetimes.values()) {\r\n const resource = lifetime.resource;\r\n if (resource.kind !== 'imported') {\r\n continue;\r\n }\r\n this._importedTextureAliases.set(resource.id, resource.physicalId);\r\n const texture = physicalToTexture.get(resource.physicalId);\r\n if (texture !== undefined) {\r\n this._resolvedImportedTextures.set(resource.id, texture);\r\n this._resolvedImportedTextures.set(resource.physicalId, texture);\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _runCleanupCallbacks(): void {\r\n let error: unknown = null;\r\n while (this._cleanupCallbacks.length > 0) {\r\n const callback = this._cleanupCallbacks.pop()!;\r\n try {\r\n callback();\r\n } catch (e) {\r\n error ??= e;\r\n }\r\n }\r\n if (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _createFramebuffer(desc: RGFramebufferDesc, autoCleanup = true): TFramebuffer {\r\n if (!this._allocator.allocateFramebuffer || !this._allocator.releaseFramebuffer) {\r\n throw new Error('RenderGraphExecutor: framebuffer allocation is not supported by this allocator.');\r\n }\r\n const framebuffer = this._allocator.allocateFramebuffer(desc);\r\n if (autoCleanup) {\r\n this._cleanupCallbacks.push(() => {\r\n this._allocator.releaseFramebuffer!(framebuffer);\r\n });\r\n }\r\n return framebuffer;\r\n }\r\n\r\n /** @internal */\r\n private _releaseFramebuffer(framebuffer: TFramebuffer): void {\r\n if (!this._allocator.releaseFramebuffer) {\r\n throw new Error('RenderGraphExecutor: framebuffer release is not supported by this allocator.');\r\n }\r\n this._allocator.releaseFramebuffer(framebuffer);\r\n }\r\n\r\n /** @internal */\r\n private _resolveFramebufferDesc(\r\n desc: RGFramebufferDesc,\r\n accessScope?: RGPassAccessScope\r\n ): RGFramebufferDesc {\r\n const resolveAttachment = (attachment: unknown): unknown => {\r\n if (attachment instanceof RGHandle) {\r\n if (accessScope) {\r\n this._assertDeclaredAccess(accessScope, attachment, 'texture');\r\n }\r\n return this._resolveResource(attachment);\r\n }\r\n return attachment;\r\n };\r\n const colors = Array.isArray(desc.colorAttachments)\r\n ? desc.colorAttachments.map(resolveAttachment)\r\n : desc.colorAttachments\r\n ? resolveAttachment(desc.colorAttachments)\r\n : null;\r\n return {\r\n ...desc,\r\n colorAttachments: colors,\r\n depthAttachment: resolveAttachment(desc.depthAttachment)\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _resolveResource(handle: RGHandle): TTexture {\r\n const imported = this._importedTextures.get(handle._id);\r\n if (imported !== undefined) {\r\n return imported;\r\n }\r\n const resolvedImported = this._resolvedImportedTextures.get(handle._id);\r\n if (resolvedImported !== undefined) {\r\n return resolvedImported;\r\n }\r\n const importedAlias = this._importedTextureAliases.get(handle._id);\r\n if (importedAlias !== undefined) {\r\n const aliased =\r\n this._importedTextures.get(importedAlias) ?? this._resolvedImportedTextures.get(importedAlias);\r\n if (aliased !== undefined) {\r\n return aliased;\r\n }\r\n }\r\n const allocated = this._allocatedTextures.get(handle._id);\r\n if (allocated !== undefined) {\r\n return allocated;\r\n }\r\n throw new Error(\r\n `RenderGraphExecutor: cannot resolve resource \"${handle.name}\" (id=${handle._id}). ` +\r\n `It may not have been allocated yet or was already released.`\r\n );\r\n }\r\n\r\n /** @internal */\r\n private _createAccessScope(pass: RGPass): RGPassAccessScope {\r\n const accessibleIds = new Set<number>();\r\n const textureIds = new Set<number>();\r\n const framebufferIds = new Set<number>();\r\n for (const resource of pass.reads) {\r\n accessibleIds.add(resource.id);\r\n if (resource.kind === 'transient' || resource.kind === 'imported') {\r\n textureIds.add(resource.id);\r\n } else if (resource.kind === 'framebuffer') {\r\n framebufferIds.add(resource.id);\r\n }\r\n }\r\n for (const resource of pass.writes) {\r\n accessibleIds.add(resource.id);\r\n if (resource.kind === 'transient' || resource.kind === 'imported') {\r\n textureIds.add(resource.id);\r\n } else if (resource.kind === 'framebuffer') {\r\n framebufferIds.add(resource.id);\r\n }\r\n }\r\n return {\r\n passName: pass.name,\r\n accessibleIds,\r\n textureIds,\r\n framebufferIds\r\n };\r\n }\r\n\r\n /** @internal */\r\n private _assertDeclaredAccess(\r\n accessScope: RGPassAccessScope,\r\n handle: RGHandle,\r\n access: 'texture' | 'framebuffer'\r\n ): void {\r\n if (!accessScope.accessibleIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access ${access} \"${handle.name}\" ` +\r\n `without declaring a read/write dependency.`\r\n );\r\n }\r\n if (access === 'texture' && !accessScope.textureIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access \"${handle.name}\" as a texture, ` +\r\n `but it is not a texture resource.`\r\n );\r\n }\r\n if (access === 'framebuffer' && !accessScope.framebufferIds.has(handle._id)) {\r\n throw new Error(\r\n `RenderGraphExecutor: pass \"${accessScope.passName}\" tried to access \"${handle.name}\" as a framebuffer, ` +\r\n `but it is not a framebuffer resource.`\r\n );\r\n }\r\n }\r\n\r\n /** @internal */\r\n private _wrapSubpassError(passName: string, subpassName: string, error: unknown): Error {\r\n const message = error instanceof Error ? error.message : String(error);\r\n const wrapped = new Error(\r\n `RenderGraphExecutor: pass \"${passName}\" subpass \"${subpassName}\" failed: ${message}`\r\n );\r\n (wrapped as Error & { cause?: unknown }).cause = error;\r\n return wrapped;\r\n }\r\n\r\n /** @internal */\r\n private _createContext(accessScope: RGPassAccessScope): RGExecuteContext {\r\n const self = this;\r\n return {\r\n getTexture<T>(handle: RGHandle): T {\r\n self._assertDeclaredAccess(accessScope, handle, 'texture');\r\n return self._resolveResource(handle) as unknown as T;\r\n },\r\n getFramebuffer<TFramebuffer = unknown>(handle: RGHandle): TFramebuffer {\r\n self._assertDeclaredAccess(accessScope, handle, 'framebuffer');\r\n const framebuffer = self._allocatedFramebuffers.get(handle._id);\r\n if (framebuffer !== undefined) {\r\n return framebuffer as unknown as TFramebuffer;\r\n }\r\n throw new Error(\r\n `RenderGraphExecutor: cannot resolve framebuffer \"${handle.name}\" (id=${handle._id}). ` +\r\n `It may not have been allocated yet or was already released.`\r\n );\r\n },\r\n createFramebuffer<TFramebuffer = unknown>(desc: RGFramebufferDesc): TFramebuffer {\r\n return self._createFramebuffer(\r\n self._resolveFramebufferDesc(desc, accessScope)\r\n ) as unknown as TFramebuffer;\r\n },\r\n deferCleanup(callback: () => void): void {\r\n self._cleanupCallbacks.push(callback);\r\n }\r\n };\r\n }\r\n}\r\n"],"names":["DEFAULT_PROFILING_OPTIONS","enabled","graph","pass","subpass","includePendingUploads","allowCrossFrame","maxPendingFrames","label","RenderGraphExecutor","_defaultProfilingOptions","_latestProfileResult","_latestPendingProfileFrame","_latestResolvedProfileSerial","_nextProfileSerial","_importedTextures","Map","_allocatedTextures","_allocatedFramebuffers","_importedTextureAliases","_resolvedImportedTextures","_cleanupCallbacks","_pendingProfileFrames","allocator","backbufferWidth","backbufferHeight","options","_allocator","_backbufferWidth","_backbufferHeight","_profilingOptions","_normalizeProfilingOptions","profiling","device","setDefaultProfilingOptions","getLatestProfileResult","resolveProfileResult","resolvePromise","Promise","resolve","setProfilingOptions","length","setBackbufferSize","width","height","setImportedTexture","handle","texture","set","_id","execute","compiled","_resolveImportedTextureAliases","profileFrame","_beginProfileFrame","allocateAt","releaseAt","allocateFramebufferAt","releaseFramebufferAt","resId","lifetime","lifetimes","resource","kind","has","firstUse","get","push","lastUse","completed","executionError","i","orderedPasses","toAllocate","desc","size","_resolveSize","allocate","framebuffersToAllocate","framebuffer","_createFramebuffer","_resolveFramebufferDesc","passError","passProfile","_beginPassProfileScope","subpasses","accessScope","_createAccessScope","ctx","_createContext","subpassProfile","_beginSubpassProfileScope","name","executeFn","data","e","_wrapSubpassError","_endProfileScope","releaseError","framebuffersToRelease","undefined","_releaseFramebuffer","delete","toRelease","release","_finishProfileFrame","cleanupError","_runCleanupCallbacks","reset","values","clear","fallbackDevice","source","Math","max","getDevice","_getProfilingDevice","supported","getDeviceCaps","miscCaps","supportTimestampQuery","rootResult","type","queryId","durationMs","status","children","message","result","frameId","frameInfo","frameCounter","passes","root","ended","frame","serial","scopes","_beginTimestampScope","_beginProfileScope","passScope","subpassName","parent","queryEnabled","queryLabel","scope","beginTimestampQuery","endTimestampQuery","_aggregateProfileStatus","_publishProfileResult","all","map","resolveTimestampQuery","then","results","_applyTimestampResult","catch","err","Error","String","_trackPendingProfileFrame","shift","filter","pending","id","statuses","collect","node","child","includes","mode","sizeMode","scaleX","scaleY","floor","physicalToTexture","physicalId","error","callback","pop","autoCleanup","allocateFramebuffer","releaseFramebuffer","resolveAttachment","attachment","RGHandle","_assertDeclaredAccess","_resolveResource","colors","Array","isArray","colorAttachments","depthAttachment","imported","resolvedImported","importedAlias","aliased","allocated","accessibleIds","Set","textureIds","framebufferIds","reads","add","writes","passName","access","wrapped","cause","self","getTexture","getFramebuffer","createFramebuffer","deferCleanup"],"mappings":"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"}
|
|
@@ -208,6 +208,24 @@ function getLightPassColorAttachments(ctx, colorAttachment) {
|
|
|
208
208
|
sss: !!sss
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
|
+
// ─── Forward+ Graph Builder ─────────────────────────────────────────
|
|
212
|
+
/**
|
|
213
|
+
* Constructs a render graph representing the forward+ pipeline.
|
|
214
|
+
*
|
|
215
|
+
* Each step in the existing `SceneRenderer._renderScene` becomes a graph pass.
|
|
216
|
+
* Execute callbacks delegate to the existing rendering code, sharing a mutable
|
|
217
|
+
* `FrameState`.
|
|
218
|
+
*
|
|
219
|
+
* @param graph - The render graph to populate.
|
|
220
|
+
* @param ctx - The draw context for this frame.
|
|
221
|
+
* @param renderQueue - The culled render queue.
|
|
222
|
+
* @param options - Pipeline feature toggles.
|
|
223
|
+
* @returns The backbuffer handle (graph output).
|
|
224
|
+
*
|
|
225
|
+
* @public
|
|
226
|
+
*/ function buildForwardPlusGraph(graph, ctx, renderQueue, options) {
|
|
227
|
+
return buildForwardPlusGraphInternal(graph, ctx, renderQueue, options).backbuffer;
|
|
228
|
+
}
|
|
211
229
|
function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
|
|
212
230
|
const backbuffer = graph.importTexture('backbuffer');
|
|
213
231
|
ctx.SSS = !!options.sss;
|
|
@@ -1082,5 +1100,5 @@ function blitToCurrentColorAttachment(ctx, source) {
|
|
|
1082
1100
|
}
|
|
1083
1101
|
}
|
|
1084
1102
|
|
|
1085
|
-
export { deriveForwardPlusOptions, executeForwardPlusGraph };
|
|
1103
|
+
export { buildForwardPlusGraph, deriveForwardPlusOptions, executeForwardPlusGraph };
|
|
1086
1104
|
//# sourceMappingURL=forward_plus_builder.js.map
|