Skip to content

Live effect parameter editing in the scaling overlay - #4

Open
Kristijan1001 wants to merge 2 commits into
SAOG0721:experimentalfrom
Kristijan1001:live-effect-parameters
Open

Live effect parameter editing in the scaling overlay#4
Kristijan1001 wants to merge 2 commits into
SAOG0721:experimentalfrom
Kristijan1001:live-effect-parameters

Conversation

@Kristijan1001

Copy link
Copy Markdown

Adds an Effect Parameters window to the scaling overlay, so effect parameters can be tuned while scaling instead of stopping scaling, editing the scaling mode, and starting again.

toolbar

panel

UI

The window is generated from EffectDesc::params, so every effect is covered without per-effect UI code:

  • labels that enumerate their values, e.g. NR Style (0 Default, 1 Natural, 2 Cinematic), become combo boxes
  • 0/1 integers become checkboxes
  • floats declared with STEP 1 and integral bounds — how frame generation declares its multiplier and toggles — get integer sliders
  • everything else is a slider snapped to the declared step

Revert restores the values the scaling session started with. Save writes the current values back into the scaling mode through a new ScalingOptions::saveEffectParameters callback.

How changes are applied

Edits are posted to the backend thread, coalesced per frame, and applied before the next render. A render is forced afterwards so the result is visible even when the source window is static.

Effect Path
Shader effects EffectDrawer::UpdateParameters rewrites the constant buffer; parameters never affect texture sizes, so no resources are rebuilt
DLSSNR Everything except NR Preset is submitted to NGX every frame, so it is swapped in place; NR Preset recreates the feature
Other native SDK backends NativeEffectBackend::UpdateParameters defaults to recreating the backend, so a backend responds correctly without implementing anything
DLSS Frame Generation The feature is rebuilt in place — _InitializeDLSSFrameGenerator was already called at runtime by the failure-recovery path
Frame Rate Filter _UpdateFrameRateLimits retunes StepTimer and the DLSSFG pacing interval

To make the frame generation multiplier changeable, the presentation ring is now allocated at MAX_SHARED_TEXTURE_SLOTS whenever frame generation is active, and the frontend opens every allocated slot. A multiplier change then only moves _sharedTextureSlotCount instead of renegotiating shared textures. StepTimer::Initialize resets its intervals first so it can run more than once.

Parameters that genuinely cannot change mid-session — XeSS frame generation, and shader effects compiled with inline parameters — are shown disabled with a note that scaling must be restarted.

The backend now keeps its own copy of the effect options, so resizing the scaling window no longer reverts live edits.

Strings

Added to Resources.language-en-US.resw and Resources.language-zh-Hans.resw. FONTS_CACHE_VERSION is bumped because the toolbar button adds an icon glyph (E9E9, the same one the scaling modes page uses for parameters).

Testing

Built with MSVC x64 and tested on an RTX 5080 against the DLSSNR and DLSSFG scaling modes.

  • DLSSNR: NR Intensity, Style, Local Tone/Structure and Skin Structure change the image immediately; NR Preset rebuilds the feature with a brief hitch.
  • DLSSFG: multiplier, Use Motion Vectors, Use Estimated Depth and Target Frame Rate rebuild the generator and retune pacing.

Two notes about CI, both pre-existing and unrelated to this change:

  • build.yml provisions no SDKs, so EnableDLSSSR / EnableDLSSFrameGeneration / EnableDLSSNR are false there and the native paths above are not exercised by CI builds. I tested with the public NVIDIA DLSS headers and import library provisioned in the workflow.
  • ARM64 + ClangCL currently fails on experimental with -Werror,-Wunused-private-field on ten fields in DLSSSRUpscaler.h and DLSSNRFilter.h, files this PR does not touch. Happy to send a separate fix for that.

Adds an Effect Parameters window to the scaling overlay so effect
parameters can be tuned without stopping scaling and switching back to
the main window.

- Toolbar toggle opens a window that builds its controls from
  EffectDesc::params, so every effect is supported without per-effect UI
  code. Labels that enumerate their values, e.g.
  "NR Style (0 Default, 1 Natural, 2 Cinematic)", become combo boxes,
  0/1 integers become checkboxes.
- Renderer::SetEffectParameter posts the change to the backend thread,
  where edits made in one frame are coalesced and applied before the
  next render. A render is forced afterwards so the result is visible
  even when the source window is static.
- Shader effects only need the constant buffer updated
  (EffectDrawer::UpdateParameters). Native SDK backends declare how they
  respond through NativeEffectBackend::UpdateParameters: the default is
  to recreate the backend, and DLSSNR applies everything but NR Preset
  in place because those parameters are submitted to NGX every frame.
- The backend now keeps its own copy of the effect options, so resizing
  the scaling window no longer reverts live edits.
- Parameters that can only be read at initialization (frame generation,
  Frame Rate Filter, and shader effects compiled with inline parameters)
  are shown disabled with a note that scaling must be restarted.
- Save writes the tuned values back to the scaling mode.
…s live

The first cut locked these two behind a restart, which left the panel
fully disabled for the DLSSFG scaling mode - the mode where the toolbar
is most useful.

- The DLSSFG presentation ring is now allocated at the maximum slot
  count whenever frame generation is active, and the frontend opens
  every allocated slot, so changing the multiplier only moves
  _sharedTextureSlotCount. Rebuilding the feature itself was already
  supported: the failure-recovery path does it mid-scaling.
- Frame rate limits moved out of _InitBackend into
  _UpdateFrameRateLimits, which both initialization and live edits call,
  so Target Frame Rate now retunes StepTimer and the DLSSFG pacing
  interval. StepTimer::Initialize resets its intervals first so it can
  run more than once.
- Parameters declared as floats with step 1 and integral bounds - which
  is how frame generation declares its multiplier and toggles - now get
  integer sliders and checkboxes instead of decimal sliders.

XeSS frame generation stays restart-only; it runs through a separate
presenter.
@SAOG0721

SAOG0721 commented Sep 1, 2026

Copy link
Copy Markdown
Owner

很好的想法 但是我编译测试了一下 可能还有很多问题 有些效果可能需要完全重载
但framerate filter的实时调节确实很好用 这个我同意 可能会考虑暂时实现其中的一部分
目前我正在调查vsr的问题 稍后我会看看能不能做一些改进

That's a great idea. I compiled and tested it, though, and it looks like there are still quite a few issues. Some effects may need to be fully reloaded for their parameters to update correctly.

I agree that being able to adjust the FrameRate Filter in real time is genuinely useful. I might consider temporarily adopting just part of this implementation.

Right now I'm investigating some issues with VSR. I'll take another look at this later and see if I can make some improvements.

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.

2 participants