From 5f73b35c0f6545c64a8d3383689febbe39dcb124 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sat, 25 Apr 2026 15:51:05 +0800 Subject: [PATCH] Add URP RenderGraph API compatibility surface --- ...nderingPipeline_CloseoutPlan_2026-04-24.md | 41 ++++----- managed/CMakeLists.txt | 3 + managed/GameScripts/RenderPipelineApiProbe.cs | 7 ++ .../ScriptableRenderContextApiSurfaceProbe.cs | 46 ++++++++++ .../Universal/ScriptableRenderPass.cs | 39 +++++++++ .../Rendering/Core/ContextContainer.cs | 87 +++++++++++++++++++ .../Rendering/Core/ContextItem.cs | 9 ++ .../Rendering/Graph/RenderGraph.cs | 34 ++++++++ 8 files changed, 246 insertions(+), 20 deletions(-) create mode 100644 managed/XCEngine.ScriptCore/Rendering/Core/ContextContainer.cs create mode 100644 managed/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs create mode 100644 managed/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.cs diff --git a/docs/plan/URP_RenderingPipeline_CloseoutPlan_2026-04-24.md b/docs/plan/URP_RenderingPipeline_CloseoutPlan_2026-04-24.md index e5d3e309..55101dd8 100644 --- a/docs/plan/URP_RenderingPipeline_CloseoutPlan_2026-04-24.md +++ b/docs/plan/URP_RenderingPipeline_CloseoutPlan_2026-04-24.md @@ -4,13 +4,13 @@ Date: 2026-04-24 ## Progress -Current plan completion: 10%. +Current plan completion: 11%. ```text -[##------------------] 10% +[##------------------] 11% ``` -Last updated: 2026-04-25 15:32. +Last updated: 2026-04-25 15:49. 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 | 14% | -| Phase 4: Managed Universal Renderer Closeout | in progress | 14% | +| Phase 3: Managed SRP Core Closeout | in progress | 15% | +| Phase 4: Managed Universal Renderer Closeout | in progress | 15% | | 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 | 9% | +| Phase 14: Testing Strategy | in progress | 10% | | Phase 15: Migration Order | open | 5% | Current basis: @@ -92,16 +92,16 @@ Plan maintenance rules: ## Execution Status -Last updated: 2026-04-25 15:32. +Last updated: 2026-04-25 15:49. -Current plan completion: 10%. +Current plan completion: 11%. 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: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. +- Executor validation at 2026-04-25 15:49 caught the editor validation up after adding the managed `RenderGraph`/`ContextContainer` API shape and `ScriptableRenderPass.RecordRenderGraph(RenderGraph, ContextContainer)` dispatch shim: `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. Unrelated dirty `new_editor/` refactor files were temporarily isolated again so the URP batch was validated against the clean editor baseline. The previous 15:07, 15:25, and 15:31 runs remain valid historical evidence; the current accepted gate is the 15:47 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 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`. +- Current scoped executor diff is managed RenderGraph API parity only: `managed/CMakeLists.txt`, `managed/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs`, `managed/XCEngine.ScriptCore/Rendering/Core/ContextContainer.cs`, `managed/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.cs`, `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs`, `managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs`, `managed/GameScripts/RenderPipelineApiProbe.cs`, and this plan. - `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` 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. +- 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`, comparison operators, and public `RecordRenderGraph(RenderGraph, ContextContainer)` dispatch; `RenderPassEvent` now carries Unity's 17.0 numeric ordering plus explicit XCEngine extension events for native scene phases and final output; managed `ContextItem`, `ContextContainer`, and `RenderGraph` compatibility types now exist. Remaining parity gaps are 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. 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. +- 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, `RenderPassEvent` ordering, `ContextContainer`, `ContextItem`, `RenderGraph`, and public `RecordRenderGraph(RenderGraph, ContextContainer)`, but future runtime assertions are still needed for complete Unity API parity behavior. +- Validation gate: current code gate passed after the managed RenderGraph/ContextContainer parity shim: `shader_tests` rebuilt and passed, `XCEngine.lib` rebuilt, `XCUIEditorApp` rebuilt, `xcengine_project_managed_assemblies` rebuilt, and the 15:47 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:47 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_154759.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:47:59 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,7 +126,7 @@ 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` 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. +- `ScriptableRenderPass` parity: local `managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs` now exposes Unity-style `renderPassEvent`, `input`, `ConfigureInput(...)`, `OnCameraSetup(...)`, `OnCameraCleanup(...)`, `OnFinishCameraStackRendering(...)`, `Execute(...)`, `profilingSampler`, ordering operators, and public virtual `RecordRenderGraph(RenderGraph, ContextContainer)`. Remaining decision: document how the public RenderGraph seam maps onto XCEngine's 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. @@ -145,15 +145,16 @@ Validation record: - 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. - 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`. +- Managed RenderGraph API evidence (2026-04-25 15:49): managed `ContextItem`, `ContextContainer`, and `XCEngine.Rendering.RenderGraphModule.RenderGraph` compatibility types were added; `ScriptableRenderPass` now exposes and dispatches public virtual `RecordRenderGraph(RenderGraph, ContextContainer)` when a pass overrides that Unity-style seam while preserving the existing protected `ScriptableRenderContext`/`RenderingData` path for current engine passes. Compile/reflection probes cover the new API surface. +- Test evidence (2026-04-25 15:49): `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:49): `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:47): 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:47:59 found no crash/assert/fatal/error/failed/device-removed/RenderGraph/shader-failure entries. +- Visual smoke evidence (2026-04-25 15:47): valid screenshot `build/new_editor/Debug/logs/smoke_scene_20260425_154759.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 the public RenderGraph/ContextContainer shape, exact command-buffer callback semantics, `BeforeRendering` mapping, and `RenderingData` class-vs-struct compatibility. +1. Continue resolving the Unity SRP/URP API parity checklist: decide 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. diff --git a/managed/CMakeLists.txt b/managed/CMakeLists.txt index 37e59aba..776e7b03 100644 --- a/managed/CMakeLists.txt +++ b/managed/CMakeLists.txt @@ -211,7 +211,10 @@ set(XCENGINE_SCRIPT_CORE_SOURCES ${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/ContextContainer.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Core/ProfilingSampler.cs + ${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.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 diff --git a/managed/GameScripts/RenderPipelineApiProbe.cs b/managed/GameScripts/RenderPipelineApiProbe.cs index 148af804..c3880427 100644 --- a/managed/GameScripts/RenderPipelineApiProbe.cs +++ b/managed/GameScripts/RenderPipelineApiProbe.cs @@ -2,6 +2,7 @@ using System; using System.Reflection; using XCEngine; using XCEngine.Rendering; +using XCEngine.Rendering.RenderGraphModule; using XCEngine.Rendering.Universal; namespace Gameplay @@ -347,6 +348,12 @@ namespace Gameplay { } + public override void RecordRenderGraph( + RenderGraph renderGraph, + ContextContainer frameData) + { + } + protected override bool RecordRenderGraph( ScriptableRenderContext context, RenderingData renderingData) diff --git a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs index d3cd9907..aa202a09 100644 --- a/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs +++ b/managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs @@ -1,6 +1,7 @@ using System.Reflection; using XCEngine; using XCEngine.Rendering; +using XCEngine.Rendering.RenderGraphModule; using XCEngine.Rendering.Universal; namespace Gameplay @@ -98,6 +99,12 @@ namespace Gameplay public bool HasRenderPassOnCameraSetup; public bool HasRenderPassOnCameraCleanup; public bool HasRenderPassOnFinishCameraStackRendering; + public bool HasContextItemType; + public bool HasContextContainerType; + public bool HasContextContainerGetOrCreate; + public bool HasRenderGraphType; + public bool HasRenderGraphAddRasterPass; + public bool HasRenderPassPublicRecordRenderGraph; public bool HasRenderPassComparisonOperators; public bool HasRenderPassEventUnityNumericOrder; public bool HasRenderPassEventEngineExtensionOrder; @@ -129,6 +136,12 @@ namespace Gameplay typeof(CommandBuffer); System.Type profilingSamplerType = typeof(ProfilingSampler); + System.Type contextItemType = + typeof(ContextItem); + System.Type contextContainerType = + typeof(ContextContainer); + System.Type renderGraphType = + typeof(RenderGraph); System.Type renderPassInputType = typeof(ScriptableRenderPassInput); System.Type universalAssemblyType = @@ -541,6 +554,39 @@ namespace Gameplay typeof(CommandBuffer) }, null) != null; + HasContextItemType = + contextItemType != null; + HasContextContainerType = + contextContainerType != null && + typeof(System.IDisposable).IsAssignableFrom( + contextContainerType); + HasContextContainerGetOrCreate = + contextContainerType.GetMethod( + "GetOrCreate", + PublicInstanceMethodFlags) != null; + HasRenderGraphType = + renderGraphType != null; + HasRenderGraphAddRasterPass = + renderGraphType.GetMethod( + "AddRasterPass", + PublicInstanceMethodFlags, + null, + new System.Type[] + { + typeof(string) + }, + null) != null; + HasRenderPassPublicRecordRenderGraph = + renderPassType.GetMethod( + "RecordRenderGraph", + PublicInstanceMethodFlags, + null, + new System.Type[] + { + typeof(RenderGraph), + typeof(ContextContainer) + }, + null) != null; HasRenderPassComparisonOperators = renderPassType.GetMethod( "op_GreaterThan", diff --git a/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs b/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs index ca2e943c..ebe94225 100644 --- a/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs +++ b/managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/ScriptableRenderPass.cs @@ -1,6 +1,8 @@ using System; +using System.Reflection; using XCEngine; using XCEngine.Rendering; +using XCEngine.Rendering.RenderGraphModule; namespace XCEngine.Rendering.Universal { @@ -81,6 +83,19 @@ namespace XCEngine.Rendering.Universal try { + if (HasPublicRenderGraphOverride()) + { + using (ContextContainer frameData = + new ContextContainer()) + { + RecordRenderGraph( + new RenderGraph(context), + frameData); + } + + return true; + } + return RecordRenderGraph( context, passRenderingData); @@ -114,6 +129,12 @@ namespace XCEngine.Rendering.Universal { } + public virtual void RecordRenderGraph( + RenderGraph renderGraph, + ContextContainer frameData) + { + } + protected virtual bool RecordRenderGraph( ScriptableRenderContext context, RenderingData renderingData) @@ -402,6 +423,24 @@ namespace XCEngine.Rendering.Universal rhs.renderPassEvent); } + private bool HasPublicRenderGraphOverride() + { + MethodInfo method = GetType().GetMethod( + nameof(RecordRenderGraph), + BindingFlags.Instance | + BindingFlags.Public, + null, + new Type[] + { + typeof(RenderGraph), + typeof(ContextContainer) + }, + null); + return method != null && + method.DeclaringType != + typeof(ScriptableRenderPass); + } + private static bool TryResolveDefaultFullscreenTargets( ScriptableRenderContext context, out RenderGraphTextureHandle sourceColor, diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ContextContainer.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ContextContainer.cs new file mode 100644 index 00000000..220e6a59 --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ContextContainer.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace XCEngine.Rendering +{ + public sealed class ContextContainer : IDisposable + { + private readonly Dictionary m_items = + new Dictionary(); + private bool m_disposed; + + public bool Contains() + where T : ContextItem + { + return m_items.ContainsKey(typeof(T)); + } + + public T Create() + where T : ContextItem, new() + { + ThrowIfDisposed(); + T item = new T(); + m_items[typeof(T)] = item; + return item; + } + + public T Get() + where T : ContextItem + { + ThrowIfDisposed(); + ContextItem item; + if (!m_items.TryGetValue( + typeof(T), + out item)) + { + throw new InvalidOperationException( + "Context item is not available: " + + typeof(T).FullName); + } + + return (T)item; + } + + public T GetOrCreate() + where T : ContextItem, new() + { + ThrowIfDisposed(); + ContextItem item; + if (m_items.TryGetValue( + typeof(T), + out item)) + { + return (T)item; + } + + return Create(); + } + + public void Dispose() + { + if (m_disposed) + { + return; + } + + foreach (ContextItem item in m_items.Values) + { + if (item != null) + { + item.Reset(); + } + } + + m_items.Clear(); + m_disposed = true; + } + + private void ThrowIfDisposed() + { + if (m_disposed) + { + throw new ObjectDisposedException( + nameof(ContextContainer)); + } + } + } +} diff --git a/managed/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs b/managed/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs new file mode 100644 index 00000000..f511c51a --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Core/ContextItem.cs @@ -0,0 +1,9 @@ +namespace XCEngine.Rendering +{ + public abstract class ContextItem + { + public virtual void Reset() + { + } + } +} diff --git a/managed/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.cs b/managed/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.cs new file mode 100644 index 00000000..436e37dc --- /dev/null +++ b/managed/XCEngine.ScriptCore/Rendering/Graph/RenderGraph.cs @@ -0,0 +1,34 @@ +using System; + +namespace XCEngine.Rendering.RenderGraphModule +{ + public sealed class RenderGraph + { + private readonly XCEngine.Rendering.ScriptableRenderContext + m_context; + + public RenderGraph() + : this(null) + { + } + + public RenderGraph( + XCEngine.Rendering.ScriptableRenderContext context) + { + m_context = context; + } + + public XCEngine.Rendering.RenderGraphRasterPassBuilder + AddRasterPass( + string passName) + { + if (m_context == null) + { + throw new InvalidOperationException( + "RenderGraph is not bound to a recording context."); + } + + return m_context.AddRasterPass(passName); + } + } +}