Skip to content

Fix upscaler-fed DLSSG resource-transition corruption - #1089

Draft
gprocunier wants to merge 1 commit into
optiscaler:masterfrom
gprocunier:dlssg-resource-lifecycle-recovery
Draft

Fix upscaler-fed DLSSG resource-transition corruption#1089
gprocunier wants to merge 1 commit into
optiscaler:masterfrom
gprocunier:dlssg-resource-lifecycle-recovery

Conversation

@gprocunier

@gprocunier gprocunier commented Aug 3, 2026

Copy link
Copy Markdown

What this fixes

This patch fixes a resource-transition failure in OptiScaler's upscaler-fed DLSSG path.

In Jump Space running native D3D12 under Proton, 3x DLSSG initially produced repeatable 3-5 second freezes when targeting HUD information panels. Continued play accumulated visible ghosting, and a later scene/resource transition produced major full-frame artifacts. Disabling frame generation removed the artifacts immediately while the FSR 4.1.1 render remained clean.

With this patch, the same 3x workload completed an 84-minute test without a freeze, ghost trail, artifact, crash, or GPU reset. Coverage included the original HUD trigger, sustained motion, ship combat, two observed NGX reset transitions, post-transition play, return to the main menu, and normal exit.

Reproducer

  • Native D3D12 (-force-d3d12), not the D3D11-to-D3D12 bridge
  • Radeon RX 9070 XT on Fedora/Proton
  • FSR 4.1.1 through OptiScaler's upscaler input
  • DLSS Enabler/Streamline providing the DLSSG backend
  • Two interpolated frames (3x output)
FGEnabled = true
FGInput = upscaler
FGOutput = DLSSGWithNvngx

[DLSSG]
InterpolationCount = 2

[OptiFG]
HUDFix = true
DisableHUDFix = false

To reproduce the original failure, load a real mission and repeatedly move the targeting reticle onto an object that opens a HUD information panel. Continue normal movement and combat through a mission or scene transition.

Before and after

Test Result
Original upscaler-fed DLSSG build at 3x Repeatable 3-5 second HUD-triggered freezes, accumulating ghosting, then full-frame artifacts after a transition
Same scene with frame generation disabled Artifacts stop immediately; FSR 4.1.1 remains clean
Patched build at 3x, LifecycleMode=1 84 minutes clean across the original HUD trigger, combat, two reset transitions, post-transition play, menu return, and normal exit

Bug and fix

The upscaler-fed path previously called EvaluateState() before capturing the current NGX reset flag and depth/motion-vector inputs. That allowed DLSSG activation and OptiScaler's per-frame resource tracking to cross a resource transition without first observing the new input boundary.

This patch moves reset and input capture before EvaluateState() and latches the lifecycle signals before the existing state handling can consume them. The tested build observed two real reset transitions cleanly:

DLSSG lifecycle signals changed: mode=observe, mask=0x4, phase=idle, validInputs=true
DLSSG lifecycle signals changed: mode=observe, mask=0x0, phase=idle, validInputs=true

That corrected path was sufficient to eliminate the original failure in testing.

The patch also includes an optional bounded recovery mode for workloads where capture and observation alone are not sufficient. It can disable DLSSG, drain submitted OptiScaler work, clear per-frame tracking, wait for consecutive valid inputs, and re-enable. A drain failure leaves frame generation disabled.

The optional active recovery mode was not needed for the verified Jump Space result. It was developed as the next bounded step during diagnosis, but the issue was already resolved with the tested observation path.

Configuration

[DLSSG]
; 0 = off, 1 = observe only, 2 = bounded recovery
LifecycleMode = auto
LifecycleWarmupFrames = auto
LifecycleDrainTimeoutMs = auto
  • LifecycleMode=0: current behavior without lifecycle logging or active recovery.
  • LifecycleMode=1: the tested path; capture lifecycle signals and log transitions without running the recovery cycle.
  • LifecycleMode=2: optional disable/drain/reset/warm/re-enable recovery.
  • Warm-up defaults to 10 valid frames and is bounded to 1-120.
  • Drain timeout defaults to 5000 ms and is bounded to 100-10000 ms.

Validation

  • The original failure was repeatable before the patch.
  • Disabling frame generation immediately cleared the corruption, isolating it from the FSR 4.1.1 upscaler and base renderer.
  • The patched LifecycleMode=1 build passed the complete 84-minute 3x regression run described above.
  • Lifecycle-controller tests cover disabled/observe behavior, warm-up counting, invalid-input reset, repeated triggers, explicit requests, fail-closed behavior, runtime-readiness loss, and sparse heartbeat logging.
  • git diff --check and project XML parsing pass.
  • The Windows Build (No Signing) passes.

Review requested

  • Is the pre-EvaluateState() upscaler-input boundary the right permanent location for reset/input capture?
  • Should the optional active recovery remain in this change, or be split into later hardening now that the tested capture path resolves the reproducer?
  • If retained, should active recovery drain the game queue as implemented or use a dedicated feature-submission fence?

@FakeMichau

Copy link
Copy Markdown
Collaborator

what

@gprocunier gprocunier changed the title Add bounded DLSSG resource lifecycle recovery RFC: recover upscaler-fed DLSSG after input resets Aug 3, 2026
@gprocunier

gprocunier commented Aug 3, 2026

Copy link
Copy Markdown
Author

Correction to my earlier wording: this patch did fix the issue in testing.

Before the patch, the native-D3D12 3x path produced repeatable HUD-triggered 3-5 second freezes, accumulating ghosting, and full-frame artifacts after a resource transition. With the patched build in LifecycleMode=1, the same trigger and workload ran cleanly for 84 minutes through HUD panels, combat, two observed reset transitions, post-transition play, menu return, and normal exit.

Mode 1 does not run the optional disable/drain/re-enable cycle, but the patch still moves reset and depth/motion-vector capture before EvaluateState() and observes the lifecycle boundary there. That tested path was sufficient to resolve the failure. Mode 2 was the next bounded recovery step mapped out during diagnosis; it was not exercised because it was not needed for the desired result.

@gprocunier gprocunier changed the title RFC: recover upscaler-fed DLSSG after input resets Fix upscaler-fed DLSSG resource-transition corruption Aug 3, 2026
@cdozdil

cdozdil commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Hi there,

Instead of generating an AI PR could you please open an Issue and share information so we can understand the problem and fix it properly?

Sorry but in this form, I would not merge this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants