Game.Rendering.Utilities.AdaptiveDynamicResolutionScale
Assembly: Assembly-CSharp
Namespace: Game.Rendering.Utilities
Type: class
Base: System.Object
Summary:
AdaptiveDynamicResolutionScale is a singleton helper that manages dynamic resolution scaling adaptively based on frame timings and GPU/CPU bottleneck heuristics. It collects per-frame timing samples, detects when the GPU is the bottleneck, and smoothly increases or decreases the internal dynamic resolution scale fraction (used by Unity's DynamicResolutionHandler). It also exposes configuration (min scale, adaptive on/off, upscaler selection) and integrates with HDAdditionalCameraData to configure upscaling where applicable.
Fields
-
private static AdaptiveDynamicResolutionScale s_Instance
Singleton instance backing field returned by the static instance property. -
public float DefaultTargetFrameRate
Target frame rate used when deciding whether to scale up/down (default 30f). -
public int EvaluationFrameCount
Number of frames over which timing samples are accumulated before making an adaptive decision (default 15). -
public uint ScaleUpDuration
Number of evaluation periods that must pass before attempting to scale up (default 4). -
public uint ScaleDownDuration
Number of evaluation periods that must pass before attempting to scale down (default 2). -
public int ScaleUpStepCount
Number of discrete steps between minScale and 1.0 when scaling up (default 5). -
public int ScaleDownStepCount
Number of discrete steps between minScale and 1.0 when scaling down (default 2). -
private const uint InitialFramesToSkip
Internal constant (1) used during initialization to skip the first frames before registering the dynamic scaler. -
private float m_AccumGPUFrameTime
Accumulator for GPU frame times over the current evaluation window. -
private float m_GPULimitedFrames
Counter (as float) of how many frames in the window were GPU-limited (incremented by 1.0 for each GPU-limited frame). -
private int m_CurrentFrameSlot
Index into the current evaluation window; incremented each frame and compared to EvaluationFrameCount. -
private uint m_ScaleUpCounter
Internal counter tracking consecutive evaluation windows that qualify for scale up. -
private uint m_ScaleDownCounter
Internal counter tracking consecutive evaluation windows that qualify for scale down. -
private static float s_CurrentScaleFraction
Current dynamic resolution scale fraction applied (0.0..1.0). Backing for currentScale property; default 1.0. -
private bool m_Initialized
Whether the internal dynamic resolution scaler has been registered/initialized. -
private uint m_InitialFrameCounter
Initial frame counter used during initialization (skips first frame(s) before calling DynamicResolutionHandler API). -
private float m_AvgGPUTime
Average GPU time computed for the last evaluation window (ms). -
private float m_AvgGPULimited
Fraction (0..1) of frames within the last evaluation window that were GPU-limited.
Properties
-
public static AdaptiveDynamicResolutionScale instance { get; }
Lazily created singleton accessor. Creates a new AdaptiveDynamicResolutionScale when first accessed. -
public DynResUpscaleFilter upscaleFilter { get; private set; }
Currently selected upscaler enum (one of the internal DynResUpscaleFilter values). Can be set via SetParams. -
public bool isEnabled { get; private set; }
Whether dynamic resolution scaling is enabled. -
public bool isAdaptive { get; private set; }
Whether the instance uses adaptive scaling logic (if false, minScale is applied as static scale when enabled). -
public float minScale { get; private set; }
Minimum allowed scale fraction (default initialized to 0.5f). When adaptive, scaling will be clamped between minScale and 1.0. -
public float currentScale { get; }
Read-only accessor returning the current dynamic resolution scale fraction (s_CurrentScaleFraction). -
public string debugState { get; }
Read-only string summarizing current state useful for debugging (reports scale and GPU-limited fraction and average GPU ms when adaptive).
Constructors
public AdaptiveDynamicResolutionScale()
No explicit constructor is declared in source — the class is instantiated via the static instance property (lazy singleton). Default member values are set in-field (e.g., DefaultTargetFrameRate, EvaluationFrameCount, minScale, s_CurrentScaleFraction).
Methods
public void SetParams(bool enabled, bool adaptive, float minScale, DynResUpscaleFilter filter, Camera camera)
Configures the dynamic resolution system:- Sets isEnabled, isAdaptive, minScale and upscaleFilter.
-
If a Camera is provided and neither DLSS nor FSR2 is active (checked via SharedSettings.instance.graphics), configures HDAdditionalCameraData to disable DLSS/FSR and sets the DynamicResolutionHandler upscaler for that camera using the mapped filter. If DLSS or FSR2 is active the selected camera is cleared from DynamicResolutionHandler.
-
private static DynamicResUpscaleFilter GetFilterFromUiEnum(DynResUpscaleFilter filter)
Maps the internal DynResUpscaleFilter enum to Unity's DynamicResUpscaleFilter enum. Throws NotSupportedException for unknown values. Note: some mappings in source intentionally swap TAAU/ContrastAdaptiveSharpen to match available Unity upscalers. -
private static bool IsGpuBottleneck(float fullFrameTime, float mainThreadCpuTime, float renderThreadCpuTime, float gpuTime)
Heuristic used to decide if the GPU is the limiting device for the given frame times. Returns true when GPU time is significantly greater than CPU times according to the implemented threshold logic. -
public void UpdateDRS(float fullFrameTime, float mainThreadCpuTime, float renderThreadCpuTime, float gpuTime)
Main per-frame update method. Behavior: - Early exits if FrameTimingManager.IsFeatureEnabled() is false.
- Initializes the DynamicResolutionHandler scaler once (after skipping initial frames).
- If not enabled, sets scale to 1.0 and returns.
- If enabled but not adaptive, sets scale to minScale and returns.
- Otherwise accumulates GPU times and GPU-limited frame counts over EvaluationFrameCount frames, computes averages, and decides to step scale up or down depending on whether average GPU time indicates the target frame time is missed and a sufficient fraction of frames are GPU-limited.
-
Uses ScaleUpDuration/ScaleDownDuration and step counts to smooth changes over time and clamps result between minScale and 1.0.
-
private static void ResetScale()
Resets s_CurrentScaleFraction to 1.0. -
public static void Dispose()
Resets the scale and clears the singleton instance (s_Instance = null). Call when shutting down or reloading to restore defaults. -
public enum DynResUpscaleFilter
Available upscaler options exposed to UI/config: - CatmullRom
- ContrastAdaptiveSharpen
- EdgeAdaptiveScaling
- TAAU
Usage Example
// Configure the adaptive dynamic resolution system once (e.g., on startup)
var drs = AdaptiveDynamicResolutionScale.instance;
drs.SetParams(
enabled: true,
adaptive: true,
minScale: 0.6f,
filter: AdaptiveDynamicResolutionScale.DynResUpscaleFilter.CatmullRom,
camera: Camera.main
);
// Each frame (or where timing data is available) call UpdateDRS with measured timings.
// fullFrameTime, mainThreadCpuTime, renderThreadCpuTime, gpuTime are in milliseconds.
drs.UpdateDRS(fullFrameTime, mainThreadCpuTime, renderThreadCpuTime, gpuTime);
// Read the currently applied resolution scale fraction
float currentScale = drs.currentScale;
// When unloading/modding shutdown, dispose to reset the singleton and scale
AdaptiveDynamicResolutionScale.Dispose();