@forgeax/engine-render 0.1.34 → 0.1.35
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/README.md +52 -3
- package/dist/assembly/device-feature-admission.d.ts +2 -2
- package/dist/assembly/host-contract.d.ts +3 -2
- package/dist/assembly/host-contract.d.ts.map +1 -1
- package/dist/assembly/recovery/renderer-recover.d.ts.map +1 -1
- package/dist/assembly/render-target-host.d.ts +5 -0
- package/dist/assembly/render-target-host.d.ts.map +1 -1
- package/dist/assembly/renderer-facade.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts +1 -0
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/authoring.mjs +2 -4
- package/dist/authoring.mjs.map +1 -1
- package/dist/chunk-3XUBWRY2.mjs +1842 -0
- package/dist/chunk-3XUBWRY2.mjs.map +1 -0
- package/dist/{chunk-UI5SFODX.mjs → chunk-G6HDNGY7.mjs} +2329 -1776
- package/dist/chunk-G6HDNGY7.mjs.map +1 -0
- package/dist/{chunk-HEB564WF.mjs → chunk-LM5IE7GF.mjs} +4 -4
- package/dist/{chunk-HEB564WF.mjs.map → chunk-LM5IE7GF.mjs.map} +1 -1
- package/dist/{chunk-MKDIT2EM.mjs → chunk-LNIUIKQ7.mjs} +143 -246
- package/dist/chunk-LNIUIKQ7.mjs.map +1 -0
- package/dist/chunk-MXTWKZO4.mjs +3268 -0
- package/dist/chunk-MXTWKZO4.mjs.map +1 -0
- package/dist/{chunk-ODZWR6JQ.mjs → chunk-MZ4C7EHF.mjs} +2042 -27
- package/dist/chunk-MZ4C7EHF.mjs.map +1 -0
- package/dist/chunk-RIPAEGI6.mjs +48 -0
- package/dist/chunk-RIPAEGI6.mjs.map +1 -0
- package/dist/{chunk-OCDLEI6I.mjs → chunk-SGPUJW3F.mjs} +117 -5
- package/dist/chunk-SGPUJW3F.mjs.map +1 -0
- package/dist/{chunk-ELJFJ2BU.mjs → chunk-X2KA6WHM.mjs} +29 -4
- package/dist/chunk-X2KA6WHM.mjs.map +1 -0
- package/dist/{chunk-BLXGONR2.mjs → chunk-XSFB7XXQ.mjs} +51 -4
- package/dist/chunk-XSFB7XXQ.mjs.map +1 -0
- package/dist/cloud/frame-context.d.ts +2 -2
- package/dist/cloud/frame-context.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +810 -2073
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/device/gpu-residency.d.ts +19 -19
- package/dist/device/gpu-residency.d.ts.map +1 -1
- package/dist/errors/render.d.ts +3 -2
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/extract/material-context.d.ts +7 -0
- package/dist/extract/material-context.d.ts.map +1 -0
- package/dist/features/host.d.ts +5 -0
- package/dist/features/host.d.ts.map +1 -1
- package/dist/features/plan.d.ts +2 -0
- package/dist/features/plan.d.ts.map +1 -1
- package/dist/features/types.d.ts +4 -0
- package/dist/features/types.d.ts.map +1 -1
- package/dist/glyph-text-layout-system.d.ts +1 -1
- package/dist/glyph-text-layout-system.d.ts.map +1 -1
- package/dist/gpu-driven/shadow-ownership.d.ts +3 -3
- package/dist/gpu-driven/shadow-ownership.d.ts.map +1 -1
- package/dist/ibl/frame-resources.d.ts.map +1 -1
- package/dist/ibl/skylight-bind-group.d.ts +4 -4
- package/dist/ibl/skylight-bind-group.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +530 -9
- package/dist/index.mjs.map +1 -1
- package/dist/instances.d.ts +3 -4
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +7 -8
- package/dist/internal.mjs.map +1 -1
- package/dist/pbr-pipeline.d.ts +3 -3
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/pipeline/standard-output/lut-gpu.d.ts +2 -2
- package/dist/pipeline/standard-output/lut-gpu.d.ts.map +1 -1
- package/dist/pipeline/standard-output/resources.d.ts +2 -2
- package/dist/pipeline/standard-output/resources.d.ts.map +1 -1
- package/dist/publication/contract.d.ts +77 -0
- package/dist/publication/contract.d.ts.map +1 -0
- package/dist/publication/dependencies.d.ts +7 -0
- package/dist/publication/dependencies.d.ts.map +1 -0
- package/dist/publication/prepare-geometry.d.ts +9 -0
- package/dist/publication/prepare-geometry.d.ts.map +1 -0
- package/dist/publication/programs.d.ts +5 -0
- package/dist/publication/programs.d.ts.map +1 -0
- package/dist/publication/publisher.d.ts +33 -0
- package/dist/publication/publisher.d.ts.map +1 -0
- package/dist/publication/receiver.d.ts +29 -0
- package/dist/publication/receiver.d.ts.map +1 -0
- package/dist/publication/resource-scope.d.ts +18 -0
- package/dist/publication/resource-scope.d.ts.map +1 -0
- package/dist/publication/targets.d.ts +33 -0
- package/dist/publication/targets.d.ts.map +1 -0
- package/dist/publication/video.d.ts +5 -0
- package/dist/publication/video.d.ts.map +1 -0
- package/dist/record/fold-buckets.d.ts +3 -3
- package/dist/record/fold-buckets.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +6 -6
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts +5 -4
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/helpers.d.ts +2 -2
- package/dist/record/helpers.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +2 -2
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass-material.d.ts +7 -9
- package/dist/record/main-pass-material.d.ts.map +1 -1
- package/dist/record/main-pass-sprite-draws.d.ts +3 -16
- package/dist/record/main-pass-sprite-draws.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/prepared-material-bindings.d.ts +3 -3
- package/dist/record/prepared-material-bindings.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +2 -2
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/sprite-instance-buffer.d.ts +31 -0
- package/dist/record/sprite-instance-buffer.d.ts.map +1 -0
- package/dist/record/target-capture-graph.d.ts +19 -0
- package/dist/record/target-capture-graph.d.ts.map +1 -0
- package/dist/record/typed-frame-graph.d.ts +2 -13
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/record/volume-params.d.ts +2 -2
- package/dist/record/volume-params.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts +5 -5
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/render-contract.d.ts +4 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +2 -0
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system-presentation.d.ts +2 -2
- package/dist/render-system-presentation.d.ts.map +1 -1
- package/dist/render-system-projections.d.ts +3 -2
- package/dist/render-system-projections.d.ts.map +1 -1
- package/dist/render-system-residency.d.ts +2 -2
- package/dist/render-system-residency.d.ts.map +1 -1
- package/dist/render-system.d.ts +3 -7
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +8 -4
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/dist/scene/render-source.d.ts +42 -0
- package/dist/scene/render-source.d.ts.map +1 -0
- package/dist/scene/source-systems.d.ts +6 -0
- package/dist/scene/source-systems.d.ts.map +1 -0
- package/dist/systems/skin-palette-allocator.d.ts.map +1 -1
- package/dist/systems/skin-palette-types.d.ts +10 -0
- package/dist/systems/skin-palette-types.d.ts.map +1 -1
- package/dist/systems/transparent-dispatch.d.ts +2 -2
- package/dist/systems/transparent-dispatch.d.ts.map +1 -1
- package/dist/systems/transparent-sort-config.d.ts +2 -1
- package/dist/systems/transparent-sort-config.d.ts.map +1 -1
- package/dist/temporal/index.mjs +6 -7
- package/package.json +21 -21
- package/src/__tests__/auto-exposure-transaction.integration.test.ts +4 -9
- package/src/__tests__/device-feature-admission.unit.test.ts +3 -2
- package/src/__tests__/gpu-driven-pbr.dawn.test.ts +3 -4
- package/src/__tests__/ktx2-basis-gpu-consumer.dawn.test.ts +4 -1
- package/src/__tests__/main-pass-material-medium-selection.unit.test.ts +0 -1
- package/src/__tests__/materials-standard-contract.unit.test.ts +0 -1
- package/src/__tests__/physical-clearcoat.integration.test.ts +23 -23
- package/src/__tests__/physical-material-budget.unit.test.ts +40 -0
- package/src/__tests__/render-error-code-owner.test-d.ts +1 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +1 -1
- package/src/assembly/device-feature-admission.ts +2 -2
- package/src/assembly/host-contract.ts +5 -2
- package/src/assembly/recovery/renderer-recover.ts +9 -0
- package/src/assembly/render-target-host.ts +57 -47
- package/src/assembly/renderer-facade.ts +3 -1
- package/src/assembly/webgpu-ready.ts +1 -1
- package/src/assembly/webgpu-renderer.ts +89 -61
- package/src/cloud/frame-context.ts +2 -2
- package/src/device/gpu-residency.ts +26 -25
- package/src/errors/render.ts +3 -1
- package/src/extract/material-context.ts +21 -0
- package/src/features/host.ts +13 -5
- package/src/features/plan.ts +2 -0
- package/src/features/types.ts +4 -0
- package/src/glyph-text-layout-system.ts +2 -2
- package/src/gpu-driven/shadow-ownership.ts +3 -3
- package/src/ibl/frame-resources.ts +0 -1
- package/src/ibl/skylight-bind-group.ts +13 -25
- package/src/index.ts +9 -0
- package/src/instances.ts +9 -6
- package/src/pbr-pipeline.ts +11 -17
- package/src/pipeline/standard-output/lut-gpu.ts +3 -3
- package/src/pipeline/standard-output/resources.ts +2 -2
- package/src/publication/__tests__/derived-geometry.integration.test.ts +177 -0
- package/src/publication/__tests__/features.integration.test.ts +122 -0
- package/src/publication/__tests__/programs.unit.test.ts +25 -0
- package/src/publication/__tests__/publication.integration.test.ts +370 -0
- package/src/publication/__tests__/targets.integration.test.ts +120 -0
- package/src/publication/__tests__/video.browser.test.ts +50 -0
- package/src/publication/contract.ts +104 -0
- package/src/publication/dependencies.ts +54 -0
- package/src/publication/prepare-geometry.ts +94 -0
- package/src/publication/programs.ts +45 -0
- package/src/publication/publisher.ts +618 -0
- package/src/publication/receiver.ts +297 -0
- package/src/publication/resource-scope.ts +31 -0
- package/src/publication/targets.ts +182 -0
- package/src/publication/video.ts +33 -0
- package/src/record/__tests__/material-bg-cache.unit.test.ts +15 -1
- package/src/record/__tests__/sprite-material-abi.unit.test.ts +8 -10
- package/src/record/__tests__/video-texture-view.unit.test.ts +9 -9
- package/src/record/fold-buckets.ts +8 -5
- package/src/record/frame-snapshot.ts +6 -6
- package/src/record/frame.ts +42 -22
- package/src/record/helpers.ts +2 -2
- package/src/record/main-pass-geometry.ts +21 -2
- package/src/record/main-pass-material.ts +37 -33
- package/src/record/main-pass-sprite-draws.ts +6 -152
- package/src/record/main-pass.ts +8 -7
- package/src/record/prepared-material-bindings.ts +11 -6
- package/src/record/render-context.ts +2 -2
- package/src/record/shadow-pass.ts +0 -3
- package/src/record/sprite-instance-buffer.ts +155 -0
- package/src/record/target-capture-graph.ts +258 -0
- package/src/record/typed-frame-graph.ts +6 -206
- package/src/record/view-ubo.ts +1 -1
- package/src/record/volume-params.ts +6 -6
- package/src/recovery/render-system-candidate.ts +10 -10
- package/src/render-contract.ts +6 -1
- package/src/render-system-extract-tail.ts +33 -17
- package/src/render-system-extract.ts +2 -0
- package/src/render-system-presentation.ts +2 -2
- package/src/render-system-projections.ts +3 -2
- package/src/render-system-residency.ts +2 -2
- package/src/render-system.ts +82 -53
- package/src/scene/render-scene.ts +110 -100
- package/src/scene/render-source.ts +90 -0
- package/src/scene/source-systems.ts +33 -0
- package/src/systems/skin-palette-allocator.ts +1 -0
- package/src/systems/skin-palette-types.ts +11 -0
- package/src/systems/transparent-dispatch.ts +2 -2
- package/src/systems/transparent-sort-config.ts +3 -1
- package/dist/chunk-BLXGONR2.mjs.map +0 -1
- package/dist/chunk-ELJFJ2BU.mjs.map +0 -1
- package/dist/chunk-ILQ5MEZF.mjs +0 -32
- package/dist/chunk-ILQ5MEZF.mjs.map +0 -1
- package/dist/chunk-MKDIT2EM.mjs.map +0 -1
- package/dist/chunk-OCDLEI6I.mjs.map +0 -1
- package/dist/chunk-ODZWR6JQ.mjs.map +0 -1
- package/dist/chunk-RXZ3RGOU.mjs +0 -53
- package/dist/chunk-RXZ3RGOU.mjs.map +0 -1
- package/dist/chunk-SHFUFJ5N.mjs +0 -1781
- package/dist/chunk-SHFUFJ5N.mjs.map +0 -1
- package/dist/chunk-UI5SFODX.mjs.map +0 -1
- package/dist/chunk-UINHLCZA.mjs +0 -2389
- package/dist/chunk-UINHLCZA.mjs.map +0 -1
- package/dist/chunk-WEX45HKH.mjs +0 -1524
- package/dist/chunk-WEX45HKH.mjs.map +0 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import type { RenderGraphBuilder, RenderGraphError } from '@forgeax/engine-render-graph';
|
|
2
|
+
import type { Texture, TextureView } from '@forgeax/engine-rhi';
|
|
3
|
+
import { ok, type Result } from '@forgeax/engine-types';
|
|
4
|
+
import type { RenderPipelineFrame } from '../render-pipeline';
|
|
5
|
+
import type { RenderTarget } from '../targets/contracts';
|
|
6
|
+
import { resolveRenderTargetMaterialSource } from '../targets/material-source';
|
|
7
|
+
import type { RenderTargetPhysical } from '../targets/physical';
|
|
8
|
+
import { encodeMainPass } from './main-pass';
|
|
9
|
+
import type { _InternalRenderPipelineContext } from './render-context';
|
|
10
|
+
import type { ReflectionProbeGraphState } from './typed-frame-graph';
|
|
11
|
+
|
|
12
|
+
export interface CubeCaptureGraphWork {
|
|
13
|
+
readonly target: RenderTarget;
|
|
14
|
+
readonly faceIndex: number;
|
|
15
|
+
readonly physical: RenderTargetPhysical;
|
|
16
|
+
readonly faceCamera: import('../render-contract').CameraSnapshot;
|
|
17
|
+
readonly viewBindGroupDynamicOffset: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CubeCaptureGraphState {
|
|
21
|
+
work: readonly CubeCaptureGraphWork[];
|
|
22
|
+
reflectionProbes?: ReflectionProbeGraphState;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function renderTargetMipCount(work: CubeCaptureGraphWork): number {
|
|
26
|
+
const { descriptor } = work.physical;
|
|
27
|
+
return descriptor.mipLevels === 1
|
|
28
|
+
? 1
|
|
29
|
+
: Math.floor(Math.log2(Math.max(descriptor.width, descriptor.height))) + 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function addTargetCaptureGraphPasses(
|
|
33
|
+
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
34
|
+
state: CubeCaptureGraphState,
|
|
35
|
+
): Result<void, RenderGraphError> {
|
|
36
|
+
for (let index = 0; index < state.work.length; index += 1) {
|
|
37
|
+
const slot = index;
|
|
38
|
+
const initial = state.work[slot];
|
|
39
|
+
if (initial === undefined) continue;
|
|
40
|
+
const current = (): CubeCaptureGraphWork => state.work[slot] ?? initial;
|
|
41
|
+
const texture = builder.importTexture(
|
|
42
|
+
`cube-capture.${slot}.texture`,
|
|
43
|
+
{
|
|
44
|
+
format: initial.physical.descriptor.format,
|
|
45
|
+
size: {
|
|
46
|
+
width: initial.physical.descriptor.width,
|
|
47
|
+
height: initial.physical.descriptor.height,
|
|
48
|
+
depthOrArrayLayers:
|
|
49
|
+
initial.physical.descriptor.sampleCount === 4 ||
|
|
50
|
+
initial.physical.descriptor.shape === '2d'
|
|
51
|
+
? 1
|
|
52
|
+
: 6,
|
|
53
|
+
},
|
|
54
|
+
mipLevelCount:
|
|
55
|
+
initial.physical.descriptor.sampleCount === 4 ? 1 : renderTargetMipCount(initial),
|
|
56
|
+
sampleCount: initial.physical.descriptor.sampleCount,
|
|
57
|
+
dimension: '2d',
|
|
58
|
+
usage: 0x10 | 0x04 | 0x01,
|
|
59
|
+
},
|
|
60
|
+
() => current().physical.colorTextures[current().faceIndex] ?? initial.physical.texture,
|
|
61
|
+
);
|
|
62
|
+
if (!texture.ok) return texture;
|
|
63
|
+
const color = builder.importView(
|
|
64
|
+
texture.value,
|
|
65
|
+
{
|
|
66
|
+
label: `cube-capture.${slot}.color`,
|
|
67
|
+
dimension: '2d',
|
|
68
|
+
baseMipLevel: 0,
|
|
69
|
+
mipLevelCount: 1,
|
|
70
|
+
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
71
|
+
arrayLayerCount: 1,
|
|
72
|
+
},
|
|
73
|
+
() =>
|
|
74
|
+
current().physical.faceViews[current().faceIndex] ??
|
|
75
|
+
initial.physical.faceViews[initial.faceIndex] ??
|
|
76
|
+
initial.physical.view,
|
|
77
|
+
);
|
|
78
|
+
if (!color.ok) return color;
|
|
79
|
+
const depthTexture = builder.importTexture(
|
|
80
|
+
`cube-capture.${slot}.depth-texture`,
|
|
81
|
+
{
|
|
82
|
+
format: 'depth24plus-stencil8',
|
|
83
|
+
size: {
|
|
84
|
+
width: initial.physical.descriptor.width,
|
|
85
|
+
height: initial.physical.descriptor.height,
|
|
86
|
+
depthOrArrayLayers:
|
|
87
|
+
initial.physical.descriptor.sampleCount === 4 ||
|
|
88
|
+
initial.physical.descriptor.shape === '2d'
|
|
89
|
+
? 1
|
|
90
|
+
: 6,
|
|
91
|
+
},
|
|
92
|
+
mipLevelCount: 1,
|
|
93
|
+
sampleCount: initial.physical.descriptor.sampleCount,
|
|
94
|
+
dimension: '2d',
|
|
95
|
+
usage: 0x10,
|
|
96
|
+
},
|
|
97
|
+
() => current().physical.depthTextures[current().faceIndex] as Texture,
|
|
98
|
+
);
|
|
99
|
+
if (!depthTexture.ok) return depthTexture;
|
|
100
|
+
const depth = builder.importView(
|
|
101
|
+
depthTexture.value,
|
|
102
|
+
{
|
|
103
|
+
label: `cube-capture.${slot}.depth`,
|
|
104
|
+
dimension: '2d',
|
|
105
|
+
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
106
|
+
arrayLayerCount: 1,
|
|
107
|
+
},
|
|
108
|
+
() => current().physical.depthViews[current().faceIndex] as TextureView,
|
|
109
|
+
);
|
|
110
|
+
if (!depth.ok) return depth;
|
|
111
|
+
const resolveTexture =
|
|
112
|
+
initial.physical.descriptor.sampleCount === 4
|
|
113
|
+
? builder.importTexture(
|
|
114
|
+
`cube-capture.${slot}.resolve-texture`,
|
|
115
|
+
{
|
|
116
|
+
format: initial.physical.descriptor.format,
|
|
117
|
+
size: {
|
|
118
|
+
width: initial.physical.descriptor.width,
|
|
119
|
+
height: initial.physical.descriptor.height,
|
|
120
|
+
depthOrArrayLayers: initial.physical.descriptor.shape === 'cube' ? 6 : 1,
|
|
121
|
+
},
|
|
122
|
+
mipLevelCount: renderTargetMipCount(initial),
|
|
123
|
+
sampleCount: 1,
|
|
124
|
+
dimension: '2d',
|
|
125
|
+
usage: 0x10 | 0x04 | 0x01,
|
|
126
|
+
},
|
|
127
|
+
() =>
|
|
128
|
+
current().physical.resolveTexture ??
|
|
129
|
+
initial.physical.resolveTexture ??
|
|
130
|
+
initial.physical.texture,
|
|
131
|
+
)
|
|
132
|
+
: undefined;
|
|
133
|
+
if (resolveTexture !== undefined && !resolveTexture.ok) return resolveTexture;
|
|
134
|
+
const resolve =
|
|
135
|
+
resolveTexture === undefined
|
|
136
|
+
? undefined
|
|
137
|
+
: builder.importView(
|
|
138
|
+
resolveTexture.value,
|
|
139
|
+
{
|
|
140
|
+
label: `cube-capture.${slot}.resolve`,
|
|
141
|
+
dimension: '2d',
|
|
142
|
+
baseMipLevel: 0,
|
|
143
|
+
mipLevelCount: 1,
|
|
144
|
+
baseArrayLayer: initial.faceIndex,
|
|
145
|
+
arrayLayerCount: 1,
|
|
146
|
+
},
|
|
147
|
+
() =>
|
|
148
|
+
current().physical.resolveFaceViews[current().faceIndex] ??
|
|
149
|
+
initial.physical.resolveFaceViews[initial.faceIndex] ??
|
|
150
|
+
initial.physical.resolveView,
|
|
151
|
+
);
|
|
152
|
+
if (resolve !== undefined && !resolve.ok) return resolve;
|
|
153
|
+
const added = builder.addRasterPass(`cube-capture-face.${slot}`, {
|
|
154
|
+
accesses: [
|
|
155
|
+
{ resource: color.value, usage: 'color-attachment' },
|
|
156
|
+
{ resource: depth.value, usage: 'depth-stencil-write' },
|
|
157
|
+
...(resolve === undefined
|
|
158
|
+
? []
|
|
159
|
+
: [{ resource: resolve.value, usage: 'color-attachment' as const }]),
|
|
160
|
+
],
|
|
161
|
+
colorAttachments: [
|
|
162
|
+
{
|
|
163
|
+
view: color.value,
|
|
164
|
+
...(resolve === undefined ? {} : { resolveTarget: resolve.value }),
|
|
165
|
+
loadOp: 'clear',
|
|
166
|
+
storeOp: 'store',
|
|
167
|
+
clearValue: () => {
|
|
168
|
+
const clear =
|
|
169
|
+
current().physical.descriptor.shape === '2d'
|
|
170
|
+
? current().faceCamera.clearColor
|
|
171
|
+
: [0, 0, 0, 1];
|
|
172
|
+
return { r: clear[0] ?? 0, g: clear[1] ?? 0, b: clear[2] ?? 0, a: clear[3] ?? 1 };
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
depthStencilAttachment: {
|
|
177
|
+
view: depth.value,
|
|
178
|
+
depthClearValue: 1,
|
|
179
|
+
depthLoadOp: 'clear',
|
|
180
|
+
depthStoreOp: 'store',
|
|
181
|
+
stencilClearValue: 0,
|
|
182
|
+
stencilLoadOp: 'clear',
|
|
183
|
+
stencilStoreOp: 'store',
|
|
184
|
+
},
|
|
185
|
+
encode: ({ pass, frame, resources }) => {
|
|
186
|
+
const internal = frame as _InternalRenderPipelineContext;
|
|
187
|
+
const captureColor = resources.textureView(color.value);
|
|
188
|
+
if (!captureColor.ok) return;
|
|
189
|
+
const captureDepth = resources.textureView(depth.value);
|
|
190
|
+
if (!captureDepth.ok) return;
|
|
191
|
+
const captureResolve =
|
|
192
|
+
resolve === undefined ? undefined : resources.textureView(resolve.value);
|
|
193
|
+
if (resolve !== undefined && (captureResolve === undefined || !captureResolve.ok)) return;
|
|
194
|
+
const captureResolveView = captureResolve?.ok ? captureResolve.value : null;
|
|
195
|
+
const selfSampling = new Map<number, Set<number>>();
|
|
196
|
+
for (const row of internal.validatedOrdered) {
|
|
197
|
+
for (const material of row.source.materials) {
|
|
198
|
+
if (
|
|
199
|
+
![...(material.textureSources?.values() ?? [])].some(
|
|
200
|
+
(source) => resolveRenderTargetMaterialSource(source)?.target === current().target,
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
continue;
|
|
204
|
+
let handles = selfSampling.get(row.renderableIndex);
|
|
205
|
+
if (handles === undefined) {
|
|
206
|
+
handles = new Set();
|
|
207
|
+
selfSampling.set(row.renderableIndex, handles);
|
|
208
|
+
}
|
|
209
|
+
handles.add(material.materialHandle ?? 0);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const captureContext = {
|
|
213
|
+
...internal,
|
|
214
|
+
camera: current().faceCamera,
|
|
215
|
+
targetW: current().physical.descriptor.width,
|
|
216
|
+
targetH: current().physical.descriptor.height,
|
|
217
|
+
dispatch: (internal.captureDispatch ?? internal.dispatch).filter(
|
|
218
|
+
(entry) => !selfSampling.get(entry.renderableIndex)?.has(entry.materialHandle),
|
|
219
|
+
),
|
|
220
|
+
foldDispatchPlan: null,
|
|
221
|
+
|
|
222
|
+
// Cube faces are raw scene captures, not display-camera HDR output.
|
|
223
|
+
// Select the PSO against the actual target attachment so an LDR
|
|
224
|
+
// cube target is rendered by a compatible forward pipeline.
|
|
225
|
+
tonemapActive: false,
|
|
226
|
+
skyboxActive: false,
|
|
227
|
+
transparentColorFormat: initial.physical.descriptor.format as GPUTextureFormat,
|
|
228
|
+
msaaActive: initial.physical.descriptor.sampleCount === 4,
|
|
229
|
+
viewBindGroupDynamicOffset: current().viewBindGroupDynamicOffset,
|
|
230
|
+
geometryColorView: captureColor.value,
|
|
231
|
+
geometryDepthView: captureDepth.value,
|
|
232
|
+
geometryColorResolveView: captureResolveView,
|
|
233
|
+
splitLdrSprite: false,
|
|
234
|
+
ldrSpritePassView: null,
|
|
235
|
+
};
|
|
236
|
+
delete captureContext.gpuDrivenDrawKeys;
|
|
237
|
+
delete captureContext.gpuDrivenStandardPbrFrameResources;
|
|
238
|
+
encodeMainPass(
|
|
239
|
+
captureContext,
|
|
240
|
+
pass,
|
|
241
|
+
{ LightMode: ['Forward'] },
|
|
242
|
+
{
|
|
243
|
+
colorViews: [captureColor.value],
|
|
244
|
+
colorFormats: [initial.physical.descriptor.format as GPUTextureFormat],
|
|
245
|
+
depthView: captureDepth.value,
|
|
246
|
+
passKind: 'forward',
|
|
247
|
+
clearColor:
|
|
248
|
+
current().physical.descriptor.shape === '2d'
|
|
249
|
+
? current().faceCamera.clearColor
|
|
250
|
+
: [0, 0, 0, 1],
|
|
251
|
+
},
|
|
252
|
+
);
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
if (!added.ok) return added;
|
|
256
|
+
}
|
|
257
|
+
return ok(undefined);
|
|
258
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { addTargetCaptureGraphPasses, type CubeCaptureGraphState } from './target-capture-graph';
|
|
2
|
+
|
|
3
|
+
export type { CubeCaptureGraphState, CubeCaptureGraphWork } from './target-capture-graph';
|
|
4
|
+
|
|
1
5
|
import { encodeMipmapLevel } from '@forgeax/engine-assets-runtime';
|
|
2
6
|
import {
|
|
3
7
|
type CompiledRenderGraph,
|
|
@@ -95,8 +99,6 @@ import type {
|
|
|
95
99
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
96
100
|
import { SHADOW_ATLAS_DEFAULT_FACE_SIZE, SHADOW_ATLAS_DEFAULT_LAYERS } from '../shadow-atlas';
|
|
97
101
|
import type { SsrAdmissionResult, SsrSpatialAdmission } from '../ssr/admission';
|
|
98
|
-
import type { RenderTarget } from '../targets/contracts';
|
|
99
|
-
import type { RenderTargetPhysical } from '../targets/physical';
|
|
100
102
|
import {
|
|
101
103
|
abortTemporalGpuSubmit,
|
|
102
104
|
CLOUD_HISTORY_FORMATS,
|
|
@@ -607,19 +609,6 @@ export function createTemporalGraphRoster(input: {
|
|
|
607
609
|
};
|
|
608
610
|
}
|
|
609
611
|
|
|
610
|
-
export interface CubeCaptureGraphWork {
|
|
611
|
-
readonly target: RenderTarget;
|
|
612
|
-
readonly faceIndex: number;
|
|
613
|
-
readonly physical: RenderTargetPhysical;
|
|
614
|
-
readonly faceCamera: import('../render-contract').CameraSnapshot;
|
|
615
|
-
readonly viewBindGroupDynamicOffset: number;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
export interface CubeCaptureGraphState {
|
|
619
|
-
work: readonly CubeCaptureGraphWork[];
|
|
620
|
-
reflectionProbes?: ReflectionProbeGraphState;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
612
|
export interface ReflectionProbeFilterGraphWork {
|
|
624
613
|
readonly probeIndex: number;
|
|
625
614
|
readonly faceIndex: number;
|
|
@@ -666,195 +655,6 @@ export function boundedReflectionProbeFilterWork(
|
|
|
666
655
|
return state.work.slice(0, Math.max(0, state.maxStepsPerFrame));
|
|
667
656
|
}
|
|
668
657
|
|
|
669
|
-
function renderTargetMipCount(work: CubeCaptureGraphWork): number {
|
|
670
|
-
const { descriptor } = work.physical;
|
|
671
|
-
return descriptor.mipLevels === 1
|
|
672
|
-
? 1
|
|
673
|
-
: Math.floor(Math.log2(Math.max(descriptor.width, descriptor.height))) + 1;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function addCubeCaptureGraphPasses(
|
|
677
|
-
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
678
|
-
state: CubeCaptureGraphState,
|
|
679
|
-
): Result<void, RenderGraphError> {
|
|
680
|
-
for (let index = 0; index < state.work.length; index += 1) {
|
|
681
|
-
const slot = index;
|
|
682
|
-
const initial = state.work[slot];
|
|
683
|
-
if (initial === undefined) continue;
|
|
684
|
-
const current = (): CubeCaptureGraphWork => state.work[slot] ?? initial;
|
|
685
|
-
const texture = builder.importTexture(
|
|
686
|
-
`cube-capture.${slot}.texture`,
|
|
687
|
-
{
|
|
688
|
-
format: initial.physical.descriptor.format,
|
|
689
|
-
size: {
|
|
690
|
-
width: initial.physical.descriptor.width,
|
|
691
|
-
height: initial.physical.descriptor.height,
|
|
692
|
-
depthOrArrayLayers: initial.physical.descriptor.sampleCount === 4 ? 1 : 6,
|
|
693
|
-
},
|
|
694
|
-
mipLevelCount:
|
|
695
|
-
initial.physical.descriptor.sampleCount === 4 ? 1 : renderTargetMipCount(initial),
|
|
696
|
-
sampleCount: initial.physical.descriptor.sampleCount,
|
|
697
|
-
dimension: '2d',
|
|
698
|
-
usage: 0x10 | 0x04 | 0x01,
|
|
699
|
-
},
|
|
700
|
-
() => current().physical.colorTextures[current().faceIndex] ?? initial.physical.texture,
|
|
701
|
-
);
|
|
702
|
-
if (!texture.ok) return texture;
|
|
703
|
-
const color = builder.importView(
|
|
704
|
-
texture.value,
|
|
705
|
-
{
|
|
706
|
-
label: `cube-capture.${slot}.color`,
|
|
707
|
-
dimension: '2d',
|
|
708
|
-
baseMipLevel: 0,
|
|
709
|
-
mipLevelCount: 1,
|
|
710
|
-
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
711
|
-
arrayLayerCount: 1,
|
|
712
|
-
},
|
|
713
|
-
() =>
|
|
714
|
-
current().physical.faceViews[current().faceIndex] ??
|
|
715
|
-
initial.physical.faceViews[initial.faceIndex] ??
|
|
716
|
-
initial.physical.view,
|
|
717
|
-
);
|
|
718
|
-
if (!color.ok) return color;
|
|
719
|
-
const depthTexture = builder.importTexture(
|
|
720
|
-
`cube-capture.${slot}.depth-texture`,
|
|
721
|
-
{
|
|
722
|
-
format: 'depth24plus-stencil8',
|
|
723
|
-
size: {
|
|
724
|
-
width: initial.physical.descriptor.width,
|
|
725
|
-
height: initial.physical.descriptor.height,
|
|
726
|
-
depthOrArrayLayers: initial.physical.descriptor.sampleCount === 4 ? 1 : 6,
|
|
727
|
-
},
|
|
728
|
-
mipLevelCount: 1,
|
|
729
|
-
sampleCount: initial.physical.descriptor.sampleCount,
|
|
730
|
-
dimension: '2d',
|
|
731
|
-
usage: 0x10,
|
|
732
|
-
},
|
|
733
|
-
() => current().physical.depthTextures[current().faceIndex] as Texture,
|
|
734
|
-
);
|
|
735
|
-
if (!depthTexture.ok) return depthTexture;
|
|
736
|
-
const depth = builder.importView(
|
|
737
|
-
depthTexture.value,
|
|
738
|
-
{
|
|
739
|
-
label: `cube-capture.${slot}.depth`,
|
|
740
|
-
dimension: '2d',
|
|
741
|
-
baseArrayLayer: initial.physical.descriptor.sampleCount === 4 ? 0 : initial.faceIndex,
|
|
742
|
-
arrayLayerCount: 1,
|
|
743
|
-
},
|
|
744
|
-
() => current().physical.depthViews[current().faceIndex] as TextureView,
|
|
745
|
-
);
|
|
746
|
-
if (!depth.ok) return depth;
|
|
747
|
-
const resolveTexture =
|
|
748
|
-
initial.physical.descriptor.sampleCount === 4
|
|
749
|
-
? builder.importTexture(
|
|
750
|
-
`cube-capture.${slot}.resolve-texture`,
|
|
751
|
-
{
|
|
752
|
-
format: initial.physical.descriptor.format,
|
|
753
|
-
size: {
|
|
754
|
-
width: initial.physical.descriptor.width,
|
|
755
|
-
height: initial.physical.descriptor.height,
|
|
756
|
-
depthOrArrayLayers: 6,
|
|
757
|
-
},
|
|
758
|
-
mipLevelCount: renderTargetMipCount(initial),
|
|
759
|
-
sampleCount: 1,
|
|
760
|
-
dimension: '2d',
|
|
761
|
-
usage: 0x10 | 0x04 | 0x01,
|
|
762
|
-
},
|
|
763
|
-
() =>
|
|
764
|
-
current().physical.resolveTexture ??
|
|
765
|
-
initial.physical.resolveTexture ??
|
|
766
|
-
initial.physical.texture,
|
|
767
|
-
)
|
|
768
|
-
: undefined;
|
|
769
|
-
if (resolveTexture !== undefined && !resolveTexture.ok) return resolveTexture;
|
|
770
|
-
const resolve =
|
|
771
|
-
resolveTexture === undefined
|
|
772
|
-
? undefined
|
|
773
|
-
: builder.importView(
|
|
774
|
-
resolveTexture.value,
|
|
775
|
-
{
|
|
776
|
-
label: `cube-capture.${slot}.resolve`,
|
|
777
|
-
dimension: '2d',
|
|
778
|
-
baseMipLevel: 0,
|
|
779
|
-
mipLevelCount: 1,
|
|
780
|
-
baseArrayLayer: initial.faceIndex,
|
|
781
|
-
arrayLayerCount: 1,
|
|
782
|
-
},
|
|
783
|
-
() =>
|
|
784
|
-
current().physical.resolveFaceViews[current().faceIndex] ??
|
|
785
|
-
initial.physical.resolveFaceViews[initial.faceIndex] ??
|
|
786
|
-
initial.physical.resolveView,
|
|
787
|
-
);
|
|
788
|
-
if (resolve !== undefined && !resolve.ok) return resolve;
|
|
789
|
-
const added = builder.addRasterPass(`cube-capture-face.${slot}`, {
|
|
790
|
-
accesses: [
|
|
791
|
-
{ resource: color.value, usage: 'color-attachment' },
|
|
792
|
-
{ resource: depth.value, usage: 'depth-stencil-write' },
|
|
793
|
-
...(resolve === undefined
|
|
794
|
-
? []
|
|
795
|
-
: [{ resource: resolve.value, usage: 'color-attachment' as const }]),
|
|
796
|
-
],
|
|
797
|
-
colorAttachments: [
|
|
798
|
-
{
|
|
799
|
-
view: color.value,
|
|
800
|
-
...(resolve === undefined ? {} : { resolveTarget: resolve.value }),
|
|
801
|
-
loadOp: 'clear',
|
|
802
|
-
storeOp: 'store',
|
|
803
|
-
clearValue: () => {
|
|
804
|
-
return { r: 0, g: 0, b: 0, a: 1 };
|
|
805
|
-
},
|
|
806
|
-
},
|
|
807
|
-
],
|
|
808
|
-
depthStencilAttachment: {
|
|
809
|
-
view: depth.value,
|
|
810
|
-
depthClearValue: 1,
|
|
811
|
-
depthLoadOp: 'clear',
|
|
812
|
-
depthStoreOp: 'store',
|
|
813
|
-
stencilClearValue: 0,
|
|
814
|
-
stencilLoadOp: 'clear',
|
|
815
|
-
stencilStoreOp: 'store',
|
|
816
|
-
},
|
|
817
|
-
encode: ({ pass, frame, resources }) => {
|
|
818
|
-
const internal = frame as _InternalRenderPipelineContext;
|
|
819
|
-
const captureColor = resources.textureView(color.value);
|
|
820
|
-
if (!captureColor.ok) return;
|
|
821
|
-
const captureDepth = resources.textureView(depth.value);
|
|
822
|
-
if (!captureDepth.ok) return;
|
|
823
|
-
const captureResolve =
|
|
824
|
-
resolve === undefined ? undefined : resources.textureView(resolve.value);
|
|
825
|
-
if (resolve !== undefined && (captureResolve === undefined || !captureResolve.ok)) return;
|
|
826
|
-
const captureResolveView = captureResolve?.ok ? captureResolve.value : null;
|
|
827
|
-
const captureContext = {
|
|
828
|
-
...internal,
|
|
829
|
-
camera: current().faceCamera,
|
|
830
|
-
// Cube faces are raw scene captures, not display-camera HDR output.
|
|
831
|
-
// Select the PSO against the actual target attachment so an LDR
|
|
832
|
-
// cube target is rendered by a compatible forward pipeline.
|
|
833
|
-
tonemapActive: false,
|
|
834
|
-
skyboxActive: false,
|
|
835
|
-
transparentColorFormat: initial.physical.descriptor.format as GPUTextureFormat,
|
|
836
|
-
msaaActive: initial.physical.descriptor.sampleCount === 4,
|
|
837
|
-
viewBindGroupDynamicOffset: current().viewBindGroupDynamicOffset,
|
|
838
|
-
geometryColorView: captureColor.value,
|
|
839
|
-
geometryDepthView: captureDepth.value,
|
|
840
|
-
geometryColorResolveView: captureResolveView,
|
|
841
|
-
splitLdrSprite: false,
|
|
842
|
-
ldrSpritePassView: null,
|
|
843
|
-
};
|
|
844
|
-
encodeMainPass(captureContext, pass, undefined, {
|
|
845
|
-
colorViews: [captureColor.value],
|
|
846
|
-
colorFormats: [initial.physical.descriptor.format as GPUTextureFormat],
|
|
847
|
-
depthView: captureDepth.value,
|
|
848
|
-
passKind: 'forward',
|
|
849
|
-
clearColor: [0, 0, 0, 1],
|
|
850
|
-
});
|
|
851
|
-
},
|
|
852
|
-
});
|
|
853
|
-
if (!added.ok) return added;
|
|
854
|
-
}
|
|
855
|
-
return ok(undefined);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
658
|
export function addReflectionProbeGraphPasses(
|
|
859
659
|
builder: RenderGraphBuilder<RenderPipelineFrame>,
|
|
860
660
|
state: ReflectionProbeGraphState,
|
|
@@ -2669,7 +2469,7 @@ export function ensureCompiledFrameGraph(
|
|
|
2669
2469
|
// rotation must not invalidate the graph or its cached bind groups.
|
|
2670
2470
|
occlusionQuery:
|
|
2671
2471
|
occlusion === undefined ? undefined : { active: true, sampleCount: occlusion.sampleCount },
|
|
2672
|
-
cubeCaptureSlots: cubeCaptureState?.work.
|
|
2472
|
+
cubeCaptureSlots: cubeCaptureState?.work.map((work) => work.physical.descriptor),
|
|
2673
2473
|
reflectionProbeSlots: cubeCaptureState?.reflectionProbes?.work.map((work) => [
|
|
2674
2474
|
work.probeIndex,
|
|
2675
2475
|
work.rawCaptureFace ?? -1,
|
|
@@ -2924,7 +2724,7 @@ export function ensureCompiledFrameGraph(
|
|
|
2924
2724
|
if (!reflectionProbes.ok) return reflectionProbes;
|
|
2925
2725
|
return cubeCaptureState === undefined
|
|
2926
2726
|
? ok(undefined)
|
|
2927
|
-
:
|
|
2727
|
+
: addTargetCaptureGraphPasses(builder, cubeCaptureState);
|
|
2928
2728
|
},
|
|
2929
2729
|
hasFeature: (identity) =>
|
|
2930
2730
|
projectedFeaturePlans.value.some((execution) => execution.featureIdentity === identity),
|
package/src/record/view-ubo.ts
CHANGED
|
@@ -30,7 +30,7 @@ export const POINTS_LINES_VIEW_BUFFER_SIZE =
|
|
|
30
30
|
export const VIEW_UNIFORM_SLOT_STRIDE = 1024;
|
|
31
31
|
export const POINT_SHADOW_VIEW_SLOT_COUNT = 24;
|
|
32
32
|
export const CUBE_CAPTURE_VIEW_SLOT_BASE = 1 + POINT_SHADOW_VIEW_SLOT_COUNT;
|
|
33
|
-
export const REFLECTION_PROBE_VIEW_SLOT_BASE = CUBE_CAPTURE_VIEW_SLOT_BASE + 6;
|
|
33
|
+
export const REFLECTION_PROBE_VIEW_SLOT_BASE = CUBE_CAPTURE_VIEW_SLOT_BASE + 6 + 1;
|
|
34
34
|
export const REFLECTION_PROBE_VIEW_SLOT_COUNT = 16;
|
|
35
35
|
export const VIEW_UNIFORM_BUFFER_SIZE =
|
|
36
36
|
VIEW_UNIFORM_SLOT_STRIDE * (REFLECTION_PROBE_VIEW_SLOT_BASE + REFLECTION_PROBE_VIEW_SLOT_COUNT);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { World } from '@forgeax/engine-ecs';
|
|
2
1
|
import { vec3 } from '@forgeax/engine-math';
|
|
3
2
|
import { type Buffer, RhiError } from '@forgeax/engine-rhi';
|
|
4
3
|
import { GPU_BUFFER_USAGE_COPY_DST, GPU_BUFFER_USAGE_UNIFORM } from '../gpu-usage';
|
|
4
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
5
5
|
import type { SpotLightProjectorFrameContext, VolumetricFogFrameContext } from '../render-contract';
|
|
6
6
|
import type { ExtractedLights, ExtractedVolumetricFog } from '../render-system-extract';
|
|
7
7
|
import { VOLUMETRIC_FOG_PARAMS_BYTES } from '../volume/resources';
|
|
@@ -57,8 +57,8 @@ export function stageVolumetricFogParams(
|
|
|
57
57
|
function prepareVolumetricFogMember(
|
|
58
58
|
internals: RenderSystemInternals,
|
|
59
59
|
frameState: RenderFrameState,
|
|
60
|
-
world:
|
|
61
|
-
worlds: readonly
|
|
60
|
+
world: RenderResourceScope,
|
|
61
|
+
worlds: readonly RenderResourceScope[],
|
|
62
62
|
fog: ExtractedVolumetricFog | undefined,
|
|
63
63
|
lights: ExtractedLights,
|
|
64
64
|
volumeCapability: boolean,
|
|
@@ -157,7 +157,7 @@ function prepareVolumetricFogMember(
|
|
|
157
157
|
frameState.temporalFrame !== undefined && frameState.temporalFrame.resetReason === 'none'
|
|
158
158
|
? 1
|
|
159
159
|
: 0;
|
|
160
|
-
//
|
|
160
|
+
// RenderResourceScope elapsed time is the sole authored-medium clock.
|
|
161
161
|
params[32] = fog.worldTimeSeconds ?? 0;
|
|
162
162
|
return {
|
|
163
163
|
densityTexture: resident.value.texture.handle,
|
|
@@ -180,8 +180,8 @@ function prepareVolumetricFogMember(
|
|
|
180
180
|
export function prepareVolumetricFogFrame(
|
|
181
181
|
internals: RenderSystemInternals,
|
|
182
182
|
frameState: RenderFrameState,
|
|
183
|
-
world:
|
|
184
|
-
worlds: readonly
|
|
183
|
+
world: RenderResourceScope,
|
|
184
|
+
worlds: readonly RenderResourceScope[],
|
|
185
185
|
fog: ExtractedVolumetricFog | undefined,
|
|
186
186
|
lights: ExtractedLights,
|
|
187
187
|
volumeCapability: boolean,
|
|
@@ -47,6 +47,7 @@ import type { PipelineBuilderShaderModuleFactory } from '../pipeline-builder';
|
|
|
47
47
|
import { standardTopologyVariantSet } from '../pipeline-spec';
|
|
48
48
|
import { inspectPointShadow } from '../point-shadow-inspection';
|
|
49
49
|
import type { PreparedGraphicsResolver } from '../prepare/prepared-graphics-resolver';
|
|
50
|
+
import type { RenderResourceScope } from '../publication/resource-scope';
|
|
50
51
|
import { gpuDrivenMeshesForFrame, validateRenderables } from '../record/frame';
|
|
51
52
|
import { prepareFrameLighting } from '../record/frame-lighting';
|
|
52
53
|
import type { RenderFrameState, ValidatedRenderable } from '../record/frame-snapshot';
|
|
@@ -95,19 +96,19 @@ export interface PreparedResolverCaches {
|
|
|
95
96
|
readonly preparedGroup0Pipelines: WeakSet<object>;
|
|
96
97
|
readonly preparedViewOnlyPipelines: WeakSet<object>;
|
|
97
98
|
readonly preparedRenderMaterialPipelines: WeakSet<object>;
|
|
98
|
-
readonly preparedAssetHandles: WeakMap<
|
|
99
|
+
readonly preparedAssetHandles: WeakMap<RenderResourceScope, Map<string, number>>;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
export interface RecoveryFrameSeed {
|
|
102
103
|
readonly frame: ExtractedFrame;
|
|
103
|
-
readonly worlds: readonly
|
|
104
|
+
readonly worlds: readonly RenderResourceScope[];
|
|
104
105
|
readonly cameraOwner: number;
|
|
105
106
|
readonly resourceOwner: number;
|
|
106
107
|
readonly width: number;
|
|
107
108
|
readonly height: number;
|
|
108
109
|
/** Last submitted Surface page is reused while the replacement device warms. */
|
|
109
110
|
readonly surfaceDynamicInput?: SurfaceDynamicInputFrame;
|
|
110
|
-
/** Last submitted
|
|
111
|
+
/** Last submitted RenderResourceScope/App time snapshot for the Surface frame ABI. */
|
|
111
112
|
readonly frameTime?: number;
|
|
112
113
|
/** Exact forward artifacts accepted by the submitted frame. */
|
|
113
114
|
readonly materialArtifacts?: ReadonlyMap<string, MaterialShaderArtifact>;
|
|
@@ -144,7 +145,7 @@ export interface RenderSystemRecoveryDependencies {
|
|
|
144
145
|
readonly createPreparedResolverFactory: (
|
|
145
146
|
runtime: RenderSystemInternals,
|
|
146
147
|
gpuWork: RenderFeatureGpuWorkOwner,
|
|
147
|
-
worlds: readonly
|
|
148
|
+
worlds: readonly RenderResourceScope[],
|
|
148
149
|
caches: PreparedResolverCaches,
|
|
149
150
|
) => (input: RenderFeaturePreparedGraphicsResolverInput) => PreparedGraphicsResolver;
|
|
150
151
|
readonly createPreparedResolverCaches: () => PreparedResolverCaches;
|
|
@@ -229,7 +230,7 @@ export function createRenderSystemRecovery(
|
|
|
229
230
|
} = deps;
|
|
230
231
|
|
|
231
232
|
// This is a detached CPU projection, retained only after queue submission.
|
|
232
|
-
// It is not a
|
|
233
|
+
// It is not a RenderResourceScope/lease cache and it never carries target or scheduler state.
|
|
233
234
|
let lastSuccessfulFrameSeed: RecoveryFrameSeed | undefined;
|
|
234
235
|
|
|
235
236
|
const createRecoveryCandidateFrameState = (): RenderFrameState => {
|
|
@@ -406,7 +407,7 @@ export function createRenderSystemRecovery(
|
|
|
406
407
|
// A successful clear-only draw can have no display camera. There is no
|
|
407
408
|
// frame graph to rehydrate in that case, but the device generation is
|
|
408
409
|
// still recoverable; the next camera-bearing draw will build its graph
|
|
409
|
-
// from the current
|
|
410
|
+
// from the current RenderResourceScope composition.
|
|
410
411
|
if (camera === undefined) return { kind: 'no-seed' };
|
|
411
412
|
|
|
412
413
|
const candidateFrameState = createRecoveryCandidateFrameState();
|
|
@@ -445,7 +446,6 @@ export function createRenderSystemRecovery(
|
|
|
445
446
|
if (pendingOutput !== undefined) retireAutoExposureGpuResources(pendingOutput);
|
|
446
447
|
candidateFrameState.pendingAutoExposureGpuResources = undefined;
|
|
447
448
|
for (const work of setupWorks) work.discard();
|
|
448
|
-
setupWorks.length = 0;
|
|
449
449
|
const graph = candidateFrameState.compiledFrameGraph;
|
|
450
450
|
candidateFrameState.compiledFrameGraph = null;
|
|
451
451
|
candidateFrameState.perFrameGraph = null;
|
|
@@ -504,7 +504,7 @@ export function createRenderSystemRecovery(
|
|
|
504
504
|
candidateFrameState,
|
|
505
505
|
runtime.internals,
|
|
506
506
|
camera,
|
|
507
|
-
seed.worlds[seed.cameraOwner] as
|
|
507
|
+
seed.worlds[seed.cameraOwner] as RenderResourceScope,
|
|
508
508
|
);
|
|
509
509
|
if (!output.ok) return failed('candidate Standard output preparation failed', output.error);
|
|
510
510
|
const gpuScene = persistentRenderScene.prepareRecoveryGpuDrivenCandidate(
|
|
@@ -514,7 +514,7 @@ export function createRenderSystemRecovery(
|
|
|
514
514
|
candidateGpuDrivenScene = gpuScene.value;
|
|
515
515
|
candidateValidated = validateRenderables(
|
|
516
516
|
runtime.internals,
|
|
517
|
-
seed.worlds[seed.cameraOwner] as
|
|
517
|
+
seed.worlds[seed.cameraOwner] as RenderResourceScope,
|
|
518
518
|
seed.worlds,
|
|
519
519
|
runtime.pipelineState,
|
|
520
520
|
candidateFrameState,
|
|
@@ -731,7 +731,7 @@ export function createRenderSystemRecovery(
|
|
|
731
731
|
cloudHistory: seed.frame.cloudLayer !== undefined,
|
|
732
732
|
});
|
|
733
733
|
const featureFrame = runRenderFeatureFrame(candidateFeatureHost, {
|
|
734
|
-
worlds: seed.worlds,
|
|
734
|
+
worlds: seed.worlds.filter((world): world is World => !('resolveAsset' in world)),
|
|
735
735
|
owner: seed.resourceOwner,
|
|
736
736
|
frameNumber: candidateFrameState.frameNumber,
|
|
737
737
|
selectedCamera: camera,
|
package/src/render-contract.ts
CHANGED
|
@@ -62,6 +62,7 @@ import type {
|
|
|
62
62
|
} from './inspection-types.js';
|
|
63
63
|
import type { InstanceCollectionInspection } from './instances.js';
|
|
64
64
|
import type { RenderExtent } from './pipeline/render-extent.js';
|
|
65
|
+
import type { PublishedRenderFrameInput, RenderPublicationIdentity } from './publication/contract';
|
|
65
66
|
import type { RenderSceneBounds } from './scene/render-scene-types.js';
|
|
66
67
|
import type { SsrAdmissionIdentity } from './ssr/identity.js';
|
|
67
68
|
import type {
|
|
@@ -446,7 +447,9 @@ export interface Renderer {
|
|
|
446
447
|
dynamicGeometryReceipt(candidate: DynamicGeometryCandidate): DynamicGeometryReceipt | undefined;
|
|
447
448
|
cancelDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
|
|
448
449
|
retireDynamicGeometry(candidate: DynamicGeometryCandidate): Result<void, DynamicGeometryError>;
|
|
449
|
-
draw(
|
|
450
|
+
draw(
|
|
451
|
+
input: RenderFrameInput | PublishedRenderFrameInput,
|
|
452
|
+
): RenderResult<FrameReceipt, RenderError>;
|
|
450
453
|
/**
|
|
451
454
|
* Arm one upcoming submitted frame for explicit color-domain observation.
|
|
452
455
|
* Observation buffers are not created, copied, mapped, or retained until a
|
|
@@ -1062,6 +1065,8 @@ export type RenderPhaseSkipReason =
|
|
|
1062
1065
|
|
|
1063
1066
|
/** First-version options bag (intentionally empty; reserved for v0.1). */
|
|
1064
1067
|
export interface RendererOptions {
|
|
1068
|
+
/** Bind a source session before receiving any publication. */
|
|
1069
|
+
readonly publicationSource?: RenderPublicationIdentity;
|
|
1065
1070
|
/** Producer-owned features installed by the renderer host. */
|
|
1066
1071
|
readonly features?: readonly RenderFeature<unknown>[] | undefined;
|
|
1067
1072
|
/** Standard profile consumed by the single renderer-owned pipeline. */
|