RenderGraph / Root-CBV investigation — 2026-09-16
Scope: read-only investigation of the existing DX12 GPU-validation log and installed HDRP/Core 17.3 source; implementation of the explicitly requested opt-in in GraphicsDriverDiagnostics.cs. No player, Editor or GPU test was started for this investigation. This is a diagnostic candidate, not a demonstrated crash repair.
What the original validation establishes
20260914-200811-track0/player.log contains 83 ID-961 errors: 61 vertex, 19 compute, 3 pixel. The first is compute dispatch 20, root parameter 0, highest accessed byte 1871, with 1792 bytes remaining in the resource from the bound address. The same unnamed compute PSO (0x000002C54D3B3110) also reports accesses to 815 and 671 with only 256 bytes remaining. A resource's remaining bytes are not necessarily the declared CBV size.
The installed ShaderVariablesGlobal.cs.hlsl declares ShaderVariablesGlobal at b0. Recomputing its HLSL packing gives 3792 bytes, with these matching accesses:
| Reported last byte | Matching global field | Field byte range |
|---|---|---|
| 335, 351, 367, 383 | _ViewProjMatrix |
320–383 |
| 671 | _PrevViewProjMatrix |
640–703 |
| 779 | _WorldSpaceCameraPos_Internal |
768–783 |
| 815 | _ScreenSize |
800–815 |
| 831 | _PostProcessScreenSize |
816–831 |
| 1871 | _EnableLightLayers |
1868–1871 |
| 1887 | _ColorPyramidLodCount |
1884–1887 |
This is a strong global-buffer binding/range clue. It is not an exact shader identification: root parameter 0 need not be register b0, and the log has no shader source or named PSO. Microsoft's root-signature example explicitly maps root indices separately from shader registers. GPU-based validation documentation identifies dispatch index as a runtime draw/dispatch count; it is not Unity compute kernel number 20.
A narrower pass candidate
In the installed HDRP source, the direct _EnableLightLayers read is Runtime/Material/Lit/Lit.hlsl:884, inside DecodeFromGBuffer. Runtime/Lighting/LightLoop/Deferred.compute:169 calls DECODE_FROM_GBUFFER and includes the Lit implementation. HDRenderPipeline.LightLoop.cs:897 schedules the Deferred Lighting RenderGraph pass and dispatches that shader through RenderComputeDeferredLighting. Its direct/indirect kernels also read _ScreenSize and camera matrices. This makes ordinary deferred lighting a strong candidate for the first compute error. Raytracing GBuffer decoding is another possible caller when enabled; the log alone cannot select the compiled variant.
The package code does not visibly allocate a 1792- or 256-byte global buffer: HDRenderPipeline.cs:1225 pushes the complete ShaderVariablesGlobal structure; Core ConstantBuffer.cs:330 allocates UnsafeUtility.SizeOf<CBType>(), and SetGlobal/Set bind its full stride at offset zero. Project source contains no custom constant-buffer binding call. Its billboard shader declares UnityPerMaterial and includes standard HDRP globals; a custom material-layout issue alone does not explain an unnamed compute PSO alternating between two remaining resource lengths. A native binding/lifetime problem is plausible but unproved.
An early capture could resolve the remaining uncertainty by inspecting the Deferred Lighting event, compute shader reflection, register/root-signature mapping, constant-buffer resource ID, GPU address/range and contents. Existing text logs cannot recover those missing objects. Capture and replay would themselves execute GPU work and are outside this investigation.
Concrete RenderGraph isolation implemented
Core RenderGraph.cs:493 defaults nativeRenderPassesEnabled to true; the 17.3 public API documentation confirms this default began with Unity 6000.3. HDRP creates new RenderGraph("HDRP") at HDRenderPipeline.cs:443 and executes it in HDRenderPipeline.RenderGraph.cs:473–477. No HDRP assignment disables the flag. Core RenderGraph.cs:1735–1752 selects the native compiler/executor or legacy compiler/executor directly from this property. No D3D11 sanitizer of this property was found in the installed managed HDRP/Core source.
D3D11 distinction: Unity's CommandBuffer.BeginRenderPass documentation describes native implementation on Metal/Vulkan and emulation on other rendering backends. Therefore the managed graph flag can affect D3D11 compilation/execution even though it does not prove a hardware/API-native render pass is active. The new log intentionally reports only managedGraphFlagBefore and managedGraphFlagAfter; nativeBackendRenderPassUsage=unverified prevents a false effectiveness claim.
-rampageNoNativeRenderPasses installs a callback before scene load and after every active pipeline construction. Only when the active pipeline is HDRenderPipeline and exactly one registered graph is named HDRP does it set that graph's property false. Other graph names are untouched; ambiguous identity fails closed with a warning. HDRP registers its graph during construction. Unity's 6000.3 RenderPipelineManager source invokes activeRenderPipelineCreated after construction and before InternalRender, so new pipeline graphs receive the override before their first render. Already-existing pipeline state is handled at initialization as well.
Validation: the changed file compiled against the installed Unity 6000.3.24f1 engine and cached Core/HDRP 17.3 assemblies with /warnaserror+: 0 errors, 0 warnings. This checks public API compatibility, not player execution or image correctness. No other rendering flag, material, frame setting or device setting was changed by this implementation.
Known issues and instancing limits
UUM-104763 is the closest confirmed constant-buffer mechanism: DX12 DrawProcedural/DispatchCompute flicker, fixed in 6000.6.0b1, still open in 6.3. The 6000.6.0f1 release notes describe avoiding constant-buffer scratch reuse outside command-buffer scope. Unity explicitly reports no DX11/Vulkan reproduction. This is not a proven common cause. Correction, 17 September: the historical full 6.6 run used older game content. Its failure does not exclude an upgrade helping the current project; no content-matched 6.3/6.6 A/B has been established. The user also reports that the old Rampage66 copy does not crash in their use.
Static review of current AlpineGrassVerge and DressingInstances instanced draws found bounded batches (maximum 256), correctly paired start/count ranges and no custom CB construction. This is not runtime proof, but there is no demonstrated array-range fix to apply. The original log's errors across compute, vertex and pixel stages also prevent attributing them specifically to D3D11 instancing. No matching official D3D11 instanced-CBV crash fix was established in this search.
The new option isolates RenderGraph compilation/pass boundaries while retaining scene content. Its result must be evaluated separately from SRP Batcher, graphics jobs, shader replacement and the historical 6.6 run with different content. Even a successful test would establish an effective workaround only for the tested configuration, not the original fault's ownership.