Add URP render pass API parity shims
This commit is contained in:
@@ -4,13 +4,13 @@ Date: 2026-04-24
|
||||
|
||||
## Progress
|
||||
|
||||
Current plan completion: 9%.
|
||||
Current plan completion: 10%.
|
||||
|
||||
```text
|
||||
[##------------------] 9%
|
||||
[##------------------] 10%
|
||||
```
|
||||
|
||||
Last updated: 2026-04-25 15:09.
|
||||
Last updated: 2026-04-25 15:32.
|
||||
|
||||
Progress definition:
|
||||
|
||||
@@ -32,8 +32,8 @@ Phase completion snapshot:
|
||||
| Phase 0: Freeze the URP Contract | in progress | 20% |
|
||||
| Phase 1: Native Pipeline and CameraFramePlan Closeout | open | 10% |
|
||||
| Phase 2: RenderGraph Productionization | in progress | 12% |
|
||||
| Phase 3: Managed SRP Core Closeout | in progress | 12% |
|
||||
| Phase 4: Managed Universal Renderer Closeout | in progress | 12% |
|
||||
| Phase 3: Managed SRP Core Closeout | in progress | 14% |
|
||||
| Phase 4: Managed Universal Renderer Closeout | in progress | 14% |
|
||||
| Phase 5: Native Builtin Passes as URP Backend Pieces | open | 5% |
|
||||
| Phase 6: ShaderLibrary Foundation | in progress | 10% |
|
||||
| Phase 7: Shader Import, Dependencies, and Compile Pipeline | in progress | 16% |
|
||||
@@ -43,7 +43,7 @@ Phase completion snapshot:
|
||||
| Phase 11: RendererFeature Assetization and Editor Workflow | open | 0% |
|
||||
| Phase 12: Post-Processing and Final Color | open | 0% |
|
||||
| Phase 13: Editor and Tooling Rendering | open | 0% |
|
||||
| Phase 14: Testing Strategy | in progress | 8% |
|
||||
| Phase 14: Testing Strategy | in progress | 9% |
|
||||
| Phase 15: Migration Order | open | 5% |
|
||||
|
||||
Current basis:
|
||||
@@ -92,16 +92,16 @@ Plan maintenance rules:
|
||||
|
||||
## Execution Status
|
||||
|
||||
Last updated: 2026-04-25 15:09.
|
||||
Last updated: 2026-04-25 15:32.
|
||||
|
||||
Current plan completion: 9%.
|
||||
Current plan completion: 10%.
|
||||
|
||||
Current position:
|
||||
|
||||
- Fresh audit restart remains active. Treat this section as the current source of truth; older build/smoke notes are only supporting evidence, not acceptance for the active workspace.
|
||||
- Executor validation at 2026-04-25 15:09 caught the editor validation back up after the managed Unity API compatibility shim was added: `shader_tests` passed, `XCEngine` rebuilt, `XCUIEditorApp` rebuilt, `xcengine_project_managed_assemblies` rebuilt, a 12s `XCUIEditor.exe` smoke passed against the rebuilt managed assemblies, a PID-selected screenshot was visually reviewed, and `runtime.log`/`crash.log` were timestamp-filtered. At 14:50 the Unity SRP/URP API parity checklist was added to this plan from official Unity URP 17.0 API references and local managed API inspection. The earlier 14:17, 14:39, and 14:54 screenshots remain valid historical evidence, but the current accepted gate is the 15:07 run.
|
||||
- Executor validation at 2026-04-25 15:32 caught the editor validation up after the managed `ScriptableRenderPass` lifecycle/input shim and `RenderPassEvent` Unity numeric-order update: `shader_tests` passed, `XCEngine` rebuilt, `XCUIEditorApp` rebuilt, `xcengine_project_managed_assemblies` rebuilt, a 12s `XCUIEditor.exe` smoke passed against the rebuilt managed assemblies, a screenshot was visually reviewed, red-dominant ratio was measured, and `runtime.log`/`crash.log` were timestamp-filtered. An intermediate build attempt failed only because unrelated dirty `new_editor/` refactor files introduced an unresolved `EditorWindowContentRuntime::RenderRequestedViewports` link dependency; the accepted gate was rerun after temporarily isolating only `new_editor/` so the URP batch was validated against the clean editor baseline. The previous 15:07 and 15:25 runs remain valid historical evidence; the current accepted gate is the 15:31 run.
|
||||
- Separate reviewer is currently unavailable; the executor is maintaining this plan directly from verified evidence. Do not touch unrelated `new_editor/` changes for this URP increment; commit/push only verified scoped batches.
|
||||
- Current non-`new_editor` executor diff is unaccepted and broader than the previous audit: `CMakeLists.txt`, `tests/CMakeLists.txt`, `engine/include/XCEngine/Core/Asset/AssetDatabase.h`, `engine/src/Core/Asset/AssetDatabase.cpp`, `engine/include/XCEngine/Resources/Shader/ShaderLoader.h`, `engine/src/Resources/Shader/ShaderLoader.cpp`, `engine/src/Resources/Shader/ShaderSourceUtils.*`, `engine/src/Resources/Shader/Internal/ShaderAuthoringInternal.h`, `engine/src/Resources/Shader/Internal/ShaderAuthoringLoader.*`, `engine/src/Resources/Shader/Internal/ShaderAuthoringShared.cpp`, `engine/src/Resources/Shader/Internal/ShaderRuntimeBuildUtils.cpp`, `engine/assets/builtin/shaders/Packages/`, `tests/Resources/Shader/test_shader_dependencies.cpp`, and `docs/plan/NewEditor_Win32WindowArchitectureRefactorPlan_2026-04-23.md`.
|
||||
- Current scoped executor diff is managed URP API parity only: `managed/CMakeLists.txt`, `managed/XCEngine.ScriptCore/Rendering/Core/CommandBuffer.cs`, `managed/XCEngine.ScriptCore/Rendering/Core/ProfilingSampler.cs`, `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPassInput.cs`, `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderPassEvent.cs`, `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs`, `managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs`, and `managed/GameScripts/RenderPipelineApiProbe.cs`.
|
||||
- `new_editor/` has separate executor changes and is intentionally not audited or modified by this reviewer pass.
|
||||
- Current package work is still a low-level ShaderLibrary/dependency-resolution restart only. Builtin runtime shader entry points must stay untouched until the dependency/compile parity work is accepted.
|
||||
- Current resolver/test progress: `ResolveBuiltinShaderPackageDependencyPath()` rejects `Packages/../...` traversal, dependency collection is recursive, missing package includes return an error string, backslash package includes are normalized, absolute includes are rejected, `AssetDatabase::ImportShaderAsset()` propagates dependency errors into the last error message, `BuildConcretePass()` expands package includes before `ShaderStageVariant::sourceCode` reaches runtime/compiler paths, and package resolution now prefers the engine source-root anchor before fallback anchors. The latest `shader_tests` run covers expanded stage source, D3D12 bytecode generation, current-directory shadow package-root rejection for existing package files, current-path fallback for package files absent from source-root, all current public package include files, AssetDatabase failed-import diagnostics, searched-anchor diagnostics, include-chain diagnostics, stale package dependency records forcing shader reimport, and an end-to-end valid package file edit producing a distinct valid shader artifact through `AssetDatabase::EnsureArtifact()` without hand-editing artifact DB rows.
|
||||
@@ -113,12 +113,12 @@ Current active blockers:
|
||||
- Commit/push gate: the user allowed verified batch commits/pushes on 2026-04-25; only commit scoped, tested URP files and keep unrelated `new_editor/` workspace changes out of these commits.
|
||||
- Runtime safety gate: do not migrate builtin runtime shader entry points, pass templates, depth/shadow/forward/final-color shaders, or ABI bindings until the low-risk resolver/test work is accepted first.
|
||||
- Unity API parity gate: public C#/native-facing rendering APIs must intentionally mirror Unity SRP/URP naming, lifecycle, and extension seams before they are accepted. Official Unity URP 17.0.4 docs show `ScriptableRendererFeature : ScriptableObject, IDisposable`, `Create()`/`AddRenderPasses(ScriptableRenderer, ref RenderingData)` as abstract entry points, `SetupRenderPasses(ScriptableRenderer, in RenderingData)`, `SetActive(bool)`, public `Dispose()` plus protected `Dispose(bool)`, and `OnCameraPreCull(...)`. The local `ScriptableRendererFeature` instead uses virtual `Create()`, by-value `AddRenderPasses(...)`, a writable `isActive` property, and an internal release pattern. Official `ScriptableRenderPass` exposes public settable `renderPassEvent`, `input`, `passName`, `profilingSampler`, `requiresIntermediateTexture`, `ConfigureInput(...)`, `OnCameraCleanup(...)`, and public virtual `RecordRenderGraph(RenderGraph, ContextContainer)`; the local pass instead uses an engine-specific protected `bool RecordRenderGraph(ScriptableRenderContext, RenderingData)`. `RenderPassEvent` is also not a cosmetic mismatch: the local enum omits Unity events such as `BeforeRendering`, GBuffer/deferred hooks, and `AfterRendering`, adds engine-specific `RenderOpaques`/`RenderSkybox`/`RenderTransparents`/final-output events, and uses local numeric ordering while `ScriptableRenderer.EnqueuePass()` sorts by `renderPassEvent`. Any deviation must be explicitly documented as an adapter, compatibility shim, or engine-specific extension; silent renames or incompatible semantics are blockers.
|
||||
- Unity API compatibility progress: `ScriptableRendererFeature` now implements `IDisposable`, exposes read-only `isActive`, `SetActive(bool)`, `SetupRenderPasses(...)`, `OnCameraPreCull(...)`, protected `Dispose(bool)`, and a `ref RenderingData` `AddRenderPasses(...)` shim while preserving existing by-value overrides; `ScriptableRenderer` now calls `SetupRenderPasses()` before `AddRenderPasses(ref ...)`; `ScriptableRenderPass.renderPassEvent` is public settable. Remaining parity gaps are `ScriptableRenderPass` input/cleanup hooks and RenderGraph API shape, `RenderPassEvent` Unity member/numeric compatibility, and the `RenderingData` class-vs-struct decision.
|
||||
- Unity API compatibility progress: `ScriptableRendererFeature` now implements `IDisposable`, exposes read-only `isActive`, `SetActive(bool)`, `SetupRenderPasses(...)`, `OnCameraPreCull(...)`, protected `Dispose(bool)`, and a `ref RenderingData` `AddRenderPasses(...)` shim while preserving existing by-value overrides; `ScriptableRenderer` calls `SetupRenderPasses()` before `AddRenderPasses(ref ...)`; `ScriptableRenderPass` now exposes public settable `renderPassEvent`, `ScriptableRenderPassInput`, `input`, `ConfigureInput(...)`, `requiresIntermediateTexture`, `Execute(...)`, `OnCameraSetup(...)`, `OnCameraCleanup(...)`, `OnFinishCameraStackRendering(...)`, protected `profilingSampler`, and comparison operators; `RenderPassEvent` now carries Unity's 17.0 numeric ordering plus explicit XCEngine extension events for native scene phases and final output. Remaining parity gaps are the public RenderGraph/ContextContainer API shape, exact functional scope for command-buffer-style callbacks, `BeforeRendering` stage semantics, and the `RenderingData` class-vs-struct decision.
|
||||
- ShaderLibrary contract gate: current package files are an incomplete starter surface and still expose old public ABI names such as `PerObjectConstants`, `MaterialConstants`, and `LightingConstants`.
|
||||
- Resolver safety gate: forward-slash package includes, backslash package includes, recursive package includes, missing package includes, absolute include rejection, `Packages/../...` traversal rejection, current-directory shadow package-root rejection, current-path fallback for source-root-missing unique package files, and searched-anchor diagnostics now have `shader_tests` evidence. Remaining resolver safety work is only ResourceManager-root fallback coverage if that fallback is expected to be supported outside editor/runtime bootstrapping.
|
||||
- Test coverage gate: `tests/Resources/Shader/test_shader_dependencies.cpp` now has executed evidence for dependency collection, package include expansion into stage source, D3D12 bytecode smoke for a temp/project-style authoring shader, current-directory shadow package-root rejection, current-path fallback resolution, all current public package include files, AssetDatabase missing-package-include failure diagnostics, actionable include diagnostics, stale package dependency records forcing reimport, and end-to-end valid package-edit artifact invalidation. It still lacks Unity API parity assertions and future complete ShaderLibrary behavior coverage.
|
||||
- Validation gate: current code gate passed after the managed Unity API compatibility shim: `shader_tests` rebuilt and passed, `XCEngine.lib` rebuilt, `XCUIEditorApp` rebuilt, `xcengine_project_managed_assemblies` rebuilt, and the 15:07 editor smoke passed. Continue to rerun the full gate after every subsequent code/test change.
|
||||
- Editor smoke gate: the accepted 2026-04-25 15:07 run reached `[app] initialize end`, closed normally with exit code 0, wrote `[trace] trace session ended`, produced `build/new_editor/Debug/logs/smoke_scene_20260425_150756.png`, and had red-dominant ratio `0.000000`. Visual review shows the Scene viewport, grid, volumetric clouds, lights, and scene objects without full red-screen regression. `runtime.log` and `crash.log` timestamp filters from 2026-04-25 15:07:56 found no crash/assert/fatal/error/failed/device-removed/RenderGraph/shader-failure entries and no crash-log entries.
|
||||
- Test coverage gate: `tests/Resources/Shader/test_shader_dependencies.cpp` now has executed evidence for dependency collection, package include expansion into stage source, D3D12 bytecode smoke for a temp/project-style authoring shader, current-directory shadow package-root rejection, current-path fallback resolution, all current public package include files, AssetDatabase missing-package-include failure diagnostics, actionable include diagnostics, stale package dependency records forcing reimport, and end-to-end valid package-edit artifact invalidation. Managed compile/reflection probes now cover the new URP pass input/lifecycle API and `RenderPassEvent` ordering, but future runtime assertions are still needed for complete Unity API parity behavior.
|
||||
- Validation gate: current code gate passed after the managed render-pass lifecycle/event parity shim: `shader_tests` rebuilt and passed, `XCEngine.lib` rebuilt, `XCUIEditorApp` rebuilt, `xcengine_project_managed_assemblies` rebuilt, and the 15:31 editor smoke passed on a clean `new_editor/` baseline. Continue to rerun the full gate after every subsequent code/test change.
|
||||
- Editor smoke gate: the accepted 2026-04-25 15:31 run reached `[app] initialize end`, closed normally with exit code 0, wrote `[trace] trace session ended`, produced `build/new_editor/Debug/logs/smoke_scene_20260425_153121.png`, and had red-dominant ratio `0.000242` from normal scene content rather than full-screen failure. Visual review shows the Scene viewport, grid, volumetric clouds, lights, and scene objects without full red-screen regression. Corrected `runtime.log` and `crash.log` timestamp filters from 2026-04-25 15:31:21 found no crash/assert/fatal/error/failed/device-removed/RenderGraph/shader-failure entries and no crash-log entries.
|
||||
- Build-scope gate: the root `CMakeLists.txt` change that conditionally skips missing `editor/CMakeLists.txt` is accepted only as build-enablement because this workspace has no `editor/` directory and the verified targets rely on the current CMake configure path. It is not counted as rendering progress by itself.
|
||||
- Scope gate: `docs/plan/NewEditor_Win32WindowArchitectureRefactorPlan_2026-04-23.md` has a very large unrelated rewrite/deletion in the current non-`new_editor` diff. It is outside this URP closeout increment and must be separated or reverted before URP acceptance.
|
||||
|
||||
@@ -126,8 +126,8 @@ Unity SRP/URP API parity checklist (open):
|
||||
|
||||
- Official reference URLs: `https://docs.unity.cn/Packages/com.unity.render-pipelines.universal%4017.0/api/UnityEngine.Rendering.Universal.ScriptableRendererFeature.html`, `https://docs.unity.cn/Packages/com.unity.render-pipelines.universal%4017.0/api/UnityEngine.Rendering.Universal.ScriptableRenderPass.html`, `https://docs.unity.cn/Packages/com.unity.render-pipelines.universal%4017.0/api/UnityEngine.Rendering.Universal.ScriptableRenderer.html`, and `https://docs.unity.cn/Packages/com.unity.render-pipelines.universal%4017.0/api/UnityEngine.Rendering.Universal.RenderPassEvent.html`.
|
||||
- `ScriptableRendererFeature` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRendererFeature.cs` must either match Unity's `ScriptableObject, IDisposable`, abstract `Create()`, abstract `AddRenderPasses(ScriptableRenderer, ref RenderingData)`, `SetupRenderPasses(ScriptableRenderer, in RenderingData)`, `OnCameraPreCull(ScriptableRenderer, in CameraData)`, read-only `isActive`, `SetActive(bool)`, public `Dispose()`, and protected `Dispose(bool)` shape, or explicitly document every incompatible engine-specific deviation.
|
||||
- `ScriptableRenderPass` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs` must either match Unity's public settable `renderPassEvent`, `input`, `ConfigureInput(...)`, `OnCameraSetup(...)`, `OnCameraCleanup(...)`, `OnFinishCameraStackRendering(...)`, and public virtual `RecordRenderGraph(RenderGraph, ContextContainer)` extension seam, or explicitly document the `ScriptableRenderContext`/`RenderingData` adapter boundary.
|
||||
- `RenderPassEvent` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderPassEvent.cs` must account for Unity's numeric ordering and members including `BeforeRendering`, GBuffer/deferred events, and `AfterRendering`; local engine-specific `RenderOpaques`, `RenderSkybox`, `RenderTransparents`, and final-output events must be documented as XCEngine extensions before public API acceptance.
|
||||
- `ScriptableRenderPass` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs` now exposes Unity-style `renderPassEvent`, `input`, `ConfigureInput(...)`, `OnCameraSetup(...)`, `OnCameraCleanup(...)`, `OnFinishCameraStackRendering(...)`, `Execute(...)`, `profilingSampler`, and ordering operators. Remaining decision: either expose Unity's public virtual `RecordRenderGraph(RenderGraph, ContextContainer)` seam or formally document the current `ScriptableRenderContext`/`RenderingData` adapter boundary.
|
||||
- `RenderPassEvent` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderPassEvent.cs` now includes Unity's numeric ordering and members including `BeforeRendering`, GBuffer/deferred events, and `AfterRendering`; local engine-specific `RenderOpaques`, `RenderSkybox`, `RenderTransparents`, and final-output events are intentionally placed as XCEngine extension points. Remaining decision: document exact `BeforeRendering` and deferred/GBuffer behavior for the current forward renderer.
|
||||
- `RenderingData` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderingData.cs` is a sealed class while Unity exposes `RenderingData` as a struct; this must be an intentional compatibility decision before renderer feature serialization or public scripting samples are accepted.
|
||||
- `ScriptableRenderer` parity: local renderer queue construction must decide whether to expose Unity-like `SetupRenderPasses(in RenderingData)` / feature setup ordering or keep the current engine-specific `BuildPassQueue()`/stage filtering model as an adapter with documented lifecycle order.
|
||||
|
||||
@@ -144,15 +144,16 @@ Validation record:
|
||||
- Unity API parity checklist evidence (2026-04-25 14:50): official Unity URP 17.0 API pages for `ScriptableRendererFeature`, `ScriptableRenderPass`, `ScriptableRenderer`, and `RenderPassEvent` were compared against local managed files under `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/`; the open checklist now records required accept-or-document decisions before public managed renderer API work proceeds.
|
||||
- Current-path package fallback evidence (2026-04-25 14:55): `shader_tests` now creates a unique package include file only under a temp project current directory, verifies source-root lookup misses it, verifies current-path fallback resolves it under the temp project package root, and verifies an existing `Core.hlsl` include is still not hijacked by a current-directory shadow package root.
|
||||
- Managed Unity API compatibility evidence (2026-04-25 15:09): `ScriptableRendererFeature` gained Unity-compatible `IDisposable`, `SetActive(bool)`, `SetupRenderPasses(...)`, `OnCameraPreCull(...)`, protected `Dispose(bool)`, and `AddRenderPasses(..., ref RenderingData)` shims; `ScriptableRenderer` now calls setup before pass injection; `ScriptableRenderPass.renderPassEvent` is public settable. Existing engine-specific paths remain intact.
|
||||
- Test evidence (2026-04-25 15:09): `cmake --build build --config Debug --target shader_tests` emitted `build/tests/Debug/shader_tests.exe`, and `ctest --test-dir build -C Debug -R shader_tests --output-on-failure` passed.
|
||||
- Build evidence (2026-04-25 15:09): `cmake --build build --config Debug --target XCEngine`, `cmake --build build --config Debug --target XCUIEditorApp`, and `cmake --build build --config Debug --target xcengine_project_managed_assemblies` all passed.
|
||||
- Runtime log evidence (2026-04-25 15:07): a 12s `XCUIEditor.exe` smoke stayed alive after managed assembly rebuild, closed normally with exit code 0, reached `[app] initialize end`, and wrote `[trace] trace session ended`; timestamp-window filtering from 15:07:56 found no crash/assert/fatal/error/failed/device-removed/RenderGraph/shader-failure entries.
|
||||
- Visual smoke evidence (2026-04-25 15:07): valid screenshot `build/new_editor/Debug/logs/smoke_scene_20260425_150756.png` was captured from a PID-enumerated `XCUIEditor.exe` visible window after forcing it topmost, shows the Scene viewport, grid, volumetric clouds, lights, and scene objects, and has red-dominant ratio `0.000000`.
|
||||
- Managed render-pass lifecycle evidence (2026-04-25 15:32): `ScriptableRenderPass` gained `ScriptableRenderPassInput`, `input`, `ConfigureInput(...)`, `requiresIntermediateTexture`, `Execute(...)`, `OnCameraSetup(...)`, `OnCameraCleanup(...)`, `OnFinishCameraStackRendering(...)`, protected `profilingSampler`, and comparison operators; `RenderPassEvent` now includes Unity 17.0 events and numeric ordering, with XCEngine `RenderOpaques`/`RenderSkybox`/`RenderTransparents`/final-output extension events placed between Unity events. Compile/reflection probes were updated to cover these public API seams.
|
||||
- Test evidence (2026-04-25 15:32): `cmake --build build --config Debug --target shader_tests` emitted `build/tests/Debug/shader_tests.exe`, and `ctest --test-dir build -C Debug -R shader_tests --output-on-failure` passed.
|
||||
- Build evidence (2026-04-25 15:32): `cmake --build build --config Debug --target XCEngine`, `cmake --build build --config Debug --target XCUIEditorApp`, and `cmake --build build --config Debug --target xcengine_project_managed_assemblies` all passed after isolating unrelated dirty `new_editor/` files.
|
||||
- Runtime log evidence (2026-04-25 15:31): a 12s `XCUIEditor.exe` smoke stayed alive after managed assembly rebuild, closed normally with exit code 0, reached `[app] initialize end`, `[app] shutdown end`, and `[trace] trace session ended`; corrected timestamp-window filtering from 15:31:21 found no crash/assert/fatal/error/failed/device-removed/RenderGraph/shader-failure entries.
|
||||
- Visual smoke evidence (2026-04-25 15:31): valid screenshot `build/new_editor/Debug/logs/smoke_scene_20260425_153121.png` was captured from the visible `XCUIEditor.exe` main window, shows the Scene viewport, grid, volumetric clouds, lights, and scene objects, and has red-dominant ratio `0.000242`.
|
||||
- Crash log evidence: no newer crash than the old 2026-04-25 02:45 `D3D12Buffer::SetData` stack was found, but the old crash remains the exact regression signature to guard against.
|
||||
|
||||
Next actions (priority order):
|
||||
|
||||
1. Continue resolving the Unity SRP/URP API parity checklist: decide `ScriptableRenderPass` input/cleanup/RenderGraph shape, `RenderPassEvent` Unity member/numeric compatibility, and `RenderingData` class-vs-struct compatibility.
|
||||
1. Continue resolving the Unity SRP/URP API parity checklist: decide the public RenderGraph/ContextContainer shape, exact command-buffer callback semantics, `BeforeRendering` mapping, and `RenderingData` class-vs-struct compatibility.
|
||||
2. Decide whether ResourceManager-root package fallback is a supported deployment path; if yes, add explicit coverage without leaving async loader threads alive in `shader_tests`.
|
||||
3. Keep builtin runtime shaders and ABI bindings unchanged until steps 1-2 are accepted.
|
||||
4. Rerun the full gate after every code/test change: `XCEngine` build, `shader_tests` build/run, `XCUIEditorApp` build, 12s `XCUIEditor.exe` smoke, screenshot review, `runtime.log` timestamp check, and `crash.log` timestamp check.
|
||||
|
||||
@@ -210,6 +210,8 @@ set(XCENGINE_SCRIPT_CORE_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/StencilOp.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/StencilState.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/CameraRenderRequestContext.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/CommandBuffer.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ProfilingSampler.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Graph/RenderGraphRasterPassBuilder.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Graph/RenderGraphTextureDesc.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Graph/RenderGraphTextureHandle.cs
|
||||
@@ -249,6 +251,7 @@ set(XCENGINE_RENDER_PIPELINES_UNIVERSAL_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ShadowCasterBlockData.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ShadowData.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPassInput.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderer.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRendererData.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRendererDataCollection.cs
|
||||
|
||||
@@ -310,6 +310,55 @@ namespace Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RenderPassLifecycleApiProbePass
|
||||
: ScriptableRenderPass
|
||||
{
|
||||
public RenderPassLifecycleApiProbePass()
|
||||
{
|
||||
renderPassEvent =
|
||||
RenderPassEvent.AfterRenderingGbuffer;
|
||||
ConfigureInput(
|
||||
ScriptableRenderPassInput.Depth |
|
||||
ScriptableRenderPassInput.Color);
|
||||
profilingSampler =
|
||||
new ProfilingSampler(
|
||||
"RenderPassLifecycleApiProbePass");
|
||||
}
|
||||
|
||||
public override void OnCameraSetup(
|
||||
CommandBuffer cmd,
|
||||
ref RenderingData renderingData)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnCameraCleanup(
|
||||
CommandBuffer cmd)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnFinishCameraStackRendering(
|
||||
CommandBuffer cmd)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Execute(
|
||||
ScriptableRenderContext context,
|
||||
ref RenderingData renderingData)
|
||||
{
|
||||
}
|
||||
|
||||
protected override bool RecordRenderGraph(
|
||||
ScriptableRenderContext context,
|
||||
RenderingData renderingData)
|
||||
{
|
||||
return input ==
|
||||
(ScriptableRenderPassInput.Depth |
|
||||
ScriptableRenderPassInput.Color) &&
|
||||
requiresIntermediateTexture &&
|
||||
profilingSampler != null;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class DefaultSceneFeature : ScriptableRendererFeature
|
||||
{
|
||||
private readonly SceneInjectionPass m_beforeOpaquePass;
|
||||
|
||||
@@ -87,6 +87,20 @@ namespace Gameplay
|
||||
public bool HasFilteringSettingsType;
|
||||
public bool HasSortingSettingsType;
|
||||
public bool HasRendererListDescType;
|
||||
public bool HasCommandBufferType;
|
||||
public bool HasProfilingSamplerType;
|
||||
public bool HasScriptableRenderPassInputType;
|
||||
public bool HasRenderPassInputProperty;
|
||||
public bool HasRenderPassConfigureInput;
|
||||
public bool HasRenderPassRequiresIntermediateTexture;
|
||||
public bool HasRenderPassProfilingSampler;
|
||||
public bool HasRenderPassExecute;
|
||||
public bool HasRenderPassOnCameraSetup;
|
||||
public bool HasRenderPassOnCameraCleanup;
|
||||
public bool HasRenderPassOnFinishCameraStackRendering;
|
||||
public bool HasRenderPassComparisonOperators;
|
||||
public bool HasRenderPassEventUnityNumericOrder;
|
||||
public bool HasRenderPassEventEngineExtensionOrder;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
@@ -109,6 +123,14 @@ namespace Gameplay
|
||||
typeof(ScriptableRendererData);
|
||||
System.Type rendererType =
|
||||
typeof(ScriptableRenderer);
|
||||
System.Type renderPassType =
|
||||
typeof(ScriptableRenderPass);
|
||||
System.Type commandBufferType =
|
||||
typeof(CommandBuffer);
|
||||
System.Type profilingSamplerType =
|
||||
typeof(ProfilingSampler);
|
||||
System.Type renderPassInputType =
|
||||
typeof(ScriptableRenderPassInput);
|
||||
System.Type universalAssemblyType =
|
||||
typeof(ScriptableRendererFeature);
|
||||
System.Reflection.Assembly universalAssembly =
|
||||
@@ -448,6 +470,124 @@ namespace Gameplay
|
||||
HasRendererListDescType =
|
||||
contextType.Assembly.GetType(
|
||||
"XCEngine.Rendering.RendererListDesc") != null;
|
||||
HasCommandBufferType =
|
||||
commandBufferType != null;
|
||||
HasProfilingSamplerType =
|
||||
profilingSamplerType != null;
|
||||
HasScriptableRenderPassInputType =
|
||||
renderPassInputType != null;
|
||||
HasRenderPassInputProperty =
|
||||
renderPassType.GetProperty(
|
||||
"input",
|
||||
PublicInstanceMethodFlags) != null;
|
||||
HasRenderPassConfigureInput =
|
||||
renderPassType.GetMethod(
|
||||
"ConfigureInput",
|
||||
PublicInstanceMethodFlags,
|
||||
null,
|
||||
new System.Type[]
|
||||
{
|
||||
typeof(ScriptableRenderPassInput)
|
||||
},
|
||||
null) != null;
|
||||
HasRenderPassRequiresIntermediateTexture =
|
||||
renderPassType.GetProperty(
|
||||
"requiresIntermediateTexture",
|
||||
PublicInstanceMethodFlags) != null;
|
||||
HasRenderPassProfilingSampler =
|
||||
renderPassType.GetProperty(
|
||||
"profilingSampler",
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.NonPublic) != null;
|
||||
HasRenderPassExecute =
|
||||
renderPassType.GetMethod(
|
||||
"Execute",
|
||||
PublicInstanceMethodFlags,
|
||||
null,
|
||||
new System.Type[]
|
||||
{
|
||||
typeof(ScriptableRenderContext),
|
||||
typeof(RenderingData).MakeByRefType()
|
||||
},
|
||||
null) != null;
|
||||
HasRenderPassOnCameraSetup =
|
||||
renderPassType.GetMethod(
|
||||
"OnCameraSetup",
|
||||
PublicInstanceMethodFlags,
|
||||
null,
|
||||
new System.Type[]
|
||||
{
|
||||
typeof(CommandBuffer),
|
||||
typeof(RenderingData).MakeByRefType()
|
||||
},
|
||||
null) != null;
|
||||
HasRenderPassOnCameraCleanup =
|
||||
renderPassType.GetMethod(
|
||||
"OnCameraCleanup",
|
||||
PublicInstanceMethodFlags,
|
||||
null,
|
||||
new System.Type[]
|
||||
{
|
||||
typeof(CommandBuffer)
|
||||
},
|
||||
null) != null;
|
||||
HasRenderPassOnFinishCameraStackRendering =
|
||||
renderPassType.GetMethod(
|
||||
"OnFinishCameraStackRendering",
|
||||
PublicInstanceMethodFlags,
|
||||
null,
|
||||
new System.Type[]
|
||||
{
|
||||
typeof(CommandBuffer)
|
||||
},
|
||||
null) != null;
|
||||
HasRenderPassComparisonOperators =
|
||||
renderPassType.GetMethod(
|
||||
"op_GreaterThan",
|
||||
BindingFlags.Static |
|
||||
BindingFlags.Public) != null &&
|
||||
renderPassType.GetMethod(
|
||||
"op_LessThan",
|
||||
BindingFlags.Static |
|
||||
BindingFlags.Public) != null;
|
||||
HasRenderPassEventUnityNumericOrder =
|
||||
(int)RenderPassEvent.BeforeRendering == 0 &&
|
||||
(int)RenderPassEvent.BeforeRenderingShadows == 50 &&
|
||||
(int)RenderPassEvent.AfterRenderingShadows == 100 &&
|
||||
(int)RenderPassEvent.BeforeRenderingPrePasses == 150 &&
|
||||
(int)RenderPassEvent.AfterRenderingPrePasses == 200 &&
|
||||
(int)RenderPassEvent.BeforeRenderingGbuffer == 210 &&
|
||||
(int)RenderPassEvent.AfterRenderingGbuffer == 220 &&
|
||||
(int)RenderPassEvent.BeforeRenderingDeferredLights == 230 &&
|
||||
(int)RenderPassEvent.AfterRenderingDeferredLights == 240 &&
|
||||
(int)RenderPassEvent.BeforeRenderingOpaques == 250 &&
|
||||
(int)RenderPassEvent.AfterRenderingOpaques == 300 &&
|
||||
(int)RenderPassEvent.BeforeRenderingSkybox == 350 &&
|
||||
(int)RenderPassEvent.AfterRenderingSkybox == 400 &&
|
||||
(int)RenderPassEvent.BeforeRenderingTransparents == 450 &&
|
||||
(int)RenderPassEvent.AfterRenderingTransparents == 500 &&
|
||||
(int)RenderPassEvent.BeforeRenderingPostProcessing == 550 &&
|
||||
(int)RenderPassEvent.AfterRenderingPostProcessing == 600 &&
|
||||
(int)RenderPassEvent.AfterRendering == 1000;
|
||||
HasRenderPassEventEngineExtensionOrder =
|
||||
(int)RenderPassEvent.BeforeRenderingOpaques <
|
||||
(int)RenderPassEvent.RenderOpaques &&
|
||||
(int)RenderPassEvent.RenderOpaques <
|
||||
(int)RenderPassEvent.AfterRenderingOpaques &&
|
||||
(int)RenderPassEvent.BeforeRenderingSkybox <
|
||||
(int)RenderPassEvent.RenderSkybox &&
|
||||
(int)RenderPassEvent.RenderSkybox <
|
||||
(int)RenderPassEvent.AfterRenderingSkybox &&
|
||||
(int)RenderPassEvent.BeforeRenderingTransparents <
|
||||
(int)RenderPassEvent.RenderTransparents &&
|
||||
(int)RenderPassEvent.RenderTransparents <
|
||||
(int)RenderPassEvent.AfterRenderingTransparents &&
|
||||
(int)RenderPassEvent.AfterRenderingPostProcessing <
|
||||
(int)RenderPassEvent.BeforeRenderingFinalOutput &&
|
||||
(int)RenderPassEvent.BeforeRenderingFinalOutput <
|
||||
(int)RenderPassEvent.AfterRendering &&
|
||||
(int)RenderPassEvent.AfterRendering <
|
||||
(int)RenderPassEvent.AfterRenderingFinalOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,23 +5,29 @@ namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public enum RenderPassEvent
|
||||
{
|
||||
BeforeRendering = 0,
|
||||
BeforeRenderingShadows = 50,
|
||||
AfterRenderingShadows = 60,
|
||||
BeforeRenderingPrePasses = 70,
|
||||
AfterRenderingPrePasses = 80,
|
||||
BeforeRenderingOpaques = 100,
|
||||
RenderOpaques = 110,
|
||||
AfterRenderingOpaques = 120,
|
||||
BeforeRenderingSkybox = 200,
|
||||
RenderSkybox = 210,
|
||||
AfterRenderingSkybox = 220,
|
||||
BeforeRenderingTransparents = 300,
|
||||
RenderTransparents = 310,
|
||||
AfterRenderingTransparents = 320,
|
||||
BeforeRenderingPostProcessing = 400,
|
||||
AfterRenderingPostProcessing = 420,
|
||||
BeforeRenderingFinalOutput = 500,
|
||||
AfterRenderingFinalOutput = 520
|
||||
AfterRenderingShadows = 100,
|
||||
BeforeRenderingPrePasses = 150,
|
||||
AfterRenderingPrePasses = 200,
|
||||
BeforeRenderingGbuffer = 210,
|
||||
AfterRenderingGbuffer = 220,
|
||||
BeforeRenderingDeferredLights = 230,
|
||||
AfterRenderingDeferredLights = 240,
|
||||
BeforeRenderingOpaques = 250,
|
||||
RenderOpaques = 275,
|
||||
AfterRenderingOpaques = 300,
|
||||
BeforeRenderingSkybox = 350,
|
||||
RenderSkybox = 375,
|
||||
AfterRenderingSkybox = 400,
|
||||
BeforeRenderingTransparents = 450,
|
||||
RenderTransparents = 475,
|
||||
AfterRenderingTransparents = 500,
|
||||
BeforeRenderingPostProcessing = 550,
|
||||
AfterRenderingPostProcessing = 600,
|
||||
BeforeRenderingFinalOutput = 900,
|
||||
AfterRendering = 1000,
|
||||
AfterRenderingFinalOutput = 1010
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ namespace XCEngine.Rendering.Universal
|
||||
"Universal.FinalColorFullscreen";
|
||||
private const string kShaderVectorFullscreenPassName =
|
||||
"Universal.ShaderVectorFullscreen";
|
||||
private readonly CommandBuffer m_lifecycleCommandBuffer =
|
||||
new CommandBuffer("ScriptableRenderPass");
|
||||
private ScriptableRenderPassInput m_input =
|
||||
ScriptableRenderPassInput.None;
|
||||
|
||||
protected ScriptableRenderPass()
|
||||
{
|
||||
@@ -20,6 +24,31 @@ namespace XCEngine.Rendering.Universal
|
||||
public RenderPassEvent renderPassEvent { get; set; } =
|
||||
RenderPassEvent.BeforeRenderingOpaques;
|
||||
|
||||
public ScriptableRenderPassInput input
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_input;
|
||||
}
|
||||
}
|
||||
|
||||
public bool requiresIntermediateTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_input != ScriptableRenderPassInput.None;
|
||||
}
|
||||
}
|
||||
|
||||
protected ProfilingSampler profilingSampler { get; set; } =
|
||||
new ProfilingSampler("Unnamed_ScriptableRenderPass");
|
||||
|
||||
public void ConfigureInput(
|
||||
ScriptableRenderPassInput passInput)
|
||||
{
|
||||
m_input = passInput;
|
||||
}
|
||||
|
||||
public virtual bool SupportsStage(
|
||||
CameraFrameStage stage)
|
||||
{
|
||||
@@ -44,14 +73,80 @@ namespace XCEngine.Rendering.Universal
|
||||
ScriptableRenderContext context,
|
||||
RenderingData renderingData)
|
||||
{
|
||||
return RecordRenderGraph(
|
||||
context,
|
||||
renderingData);
|
||||
RenderingData passRenderingData =
|
||||
renderingData;
|
||||
OnCameraSetup(
|
||||
m_lifecycleCommandBuffer,
|
||||
ref passRenderingData);
|
||||
|
||||
try
|
||||
{
|
||||
return RecordRenderGraph(
|
||||
context,
|
||||
passRenderingData);
|
||||
}
|
||||
finally
|
||||
{
|
||||
OnCameraCleanup(
|
||||
m_lifecycleCommandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract bool RecordRenderGraph(
|
||||
public virtual void Execute(
|
||||
ScriptableRenderContext context,
|
||||
RenderingData renderingData);
|
||||
ref RenderingData renderingData)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnCameraSetup(
|
||||
CommandBuffer cmd,
|
||||
ref RenderingData renderingData)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnCameraCleanup(
|
||||
CommandBuffer cmd)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnFinishCameraStackRendering(
|
||||
CommandBuffer cmd)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual bool RecordRenderGraph(
|
||||
ScriptableRenderContext context,
|
||||
RenderingData renderingData)
|
||||
{
|
||||
if (context == null ||
|
||||
renderingData == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Execute(
|
||||
context,
|
||||
ref renderingData);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator >(
|
||||
ScriptableRenderPass lhs,
|
||||
ScriptableRenderPass rhs)
|
||||
{
|
||||
return CompareRenderPassEvents(
|
||||
lhs,
|
||||
rhs) > 0;
|
||||
}
|
||||
|
||||
public static bool operator <(
|
||||
ScriptableRenderPass lhs,
|
||||
ScriptableRenderPass rhs)
|
||||
{
|
||||
return CompareRenderPassEvents(
|
||||
lhs,
|
||||
rhs) < 0;
|
||||
}
|
||||
|
||||
protected bool RecordColorScaleFullscreenPass(
|
||||
ScriptableRenderContext context,
|
||||
@@ -248,6 +343,10 @@ namespace XCEngine.Rendering.Universal
|
||||
case RenderPassEvent.AfterRenderingPrePasses:
|
||||
block = RendererBlock.DepthPrepass;
|
||||
return true;
|
||||
case RenderPassEvent.BeforeRenderingGbuffer:
|
||||
case RenderPassEvent.AfterRenderingGbuffer:
|
||||
case RenderPassEvent.BeforeRenderingDeferredLights:
|
||||
case RenderPassEvent.AfterRenderingDeferredLights:
|
||||
case RenderPassEvent.BeforeRenderingOpaques:
|
||||
case RenderPassEvent.RenderOpaques:
|
||||
case RenderPassEvent.AfterRenderingOpaques:
|
||||
@@ -268,6 +367,7 @@ namespace XCEngine.Rendering.Universal
|
||||
block = RendererBlock.PostProcess;
|
||||
return true;
|
||||
case RenderPassEvent.BeforeRenderingFinalOutput:
|
||||
case RenderPassEvent.AfterRendering:
|
||||
case RenderPassEvent.AfterRenderingFinalOutput:
|
||||
block = RendererBlock.FinalOutput;
|
||||
return true;
|
||||
@@ -277,6 +377,31 @@ namespace XCEngine.Rendering.Universal
|
||||
}
|
||||
}
|
||||
|
||||
private static int CompareRenderPassEvents(
|
||||
ScriptableRenderPass lhs,
|
||||
ScriptableRenderPass rhs)
|
||||
{
|
||||
if (ReferenceEquals(
|
||||
lhs,
|
||||
rhs))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lhs == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rhs == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return lhs.renderPassEvent.CompareTo(
|
||||
rhs.renderPassEvent);
|
||||
}
|
||||
|
||||
private static bool TryResolveDefaultFullscreenTargets(
|
||||
ScriptableRenderContext context,
|
||||
out RenderGraphTextureHandle sourceColor,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
[Flags]
|
||||
public enum ScriptableRenderPassInput
|
||||
{
|
||||
None = 0,
|
||||
Depth = 1,
|
||||
Normal = 2,
|
||||
Color = 4,
|
||||
Motion = 8
|
||||
}
|
||||
}
|
||||
18
managed/XCEngine.ScriptCore/Rendering/Core/CommandBuffer.cs
Normal file
18
managed/XCEngine.ScriptCore/Rendering/Core/CommandBuffer.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace XCEngine.Rendering
|
||||
{
|
||||
public sealed class CommandBuffer
|
||||
{
|
||||
public CommandBuffer()
|
||||
: this(string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public CommandBuffer(
|
||||
string name)
|
||||
{
|
||||
this.name = name ?? string.Empty;
|
||||
}
|
||||
|
||||
public string name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace XCEngine.Rendering
|
||||
{
|
||||
public sealed class ProfilingSampler
|
||||
{
|
||||
public ProfilingSampler(
|
||||
string name)
|
||||
{
|
||||
this.name =
|
||||
string.IsNullOrEmpty(name)
|
||||
? "Unnamed_ScriptableRenderPass"
|
||||
: name;
|
||||
}
|
||||
|
||||
public string name { get; private set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user