Skip to content

Commit

Permalink
Improving DLSS cpu load, and not recreating DLSS state every change o…
Browse files Browse the repository at this point in the history
…f res (#5231)

* Improving DRS cpu load, and not recreating DLSS state every change of resolution

Changelog

Moving complexity into the core package instead

Spaces / and formatting

Visual artifacts on hardware DRS because we were flushing the dynamic resolution too much

Removing left over changes from debugging

* Fixes from code review
  • Loading branch information
kecho committed Jul 30, 2021
1 parent 9833699 commit ad100f7
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 44 deletions.
1 change: 1 addition & 0 deletions com.unity.render-pipelines.core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Serialize the Probe Volume asset as binary to improve footprint on disk and loading speed.
- LensFlare Element editor now have Thumbnail preview
- Improved IntegrateLDCharlie() to use uniform stratified sampling for faster convergence towards the ground truth
- DynamicResolutionHandler.GetScaledSize function now clamps, and never allows to return a size greater than its input.

## [11.0.0] - 2020-10-21

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ public void Update(GlobalDynamicResolutionSettings settings, Action OnResolution
{
ProcessSettings(settings);

if (!m_Enabled && !s_ActiveInstanceDirty)
if (!m_Enabled || !s_ActiveInstanceDirty)
{
s_ActiveInstanceDirty = false;
return;
Expand Down Expand Up @@ -487,7 +487,7 @@ public void ForceSoftwareFallback()

/// <summary>
/// Applies to the passed size the scale imposed by the dynamic resolution system.
/// Note: this function has the side effect of caching the last scale size.
/// Note: this function has the side effect of caching the last scale size, and the output is always smaller or equal then the input.
/// </summary>
/// <param name="size">The starting size of the render target that will be scaled by dynamic resolution.</param>
/// <returns>The parameter size scaled by the dynamic resolution system.</returns>
Expand All @@ -501,6 +501,7 @@ public Vector2Int GetScaledSize(Vector2Int size)
}

Vector2Int scaledSize = ApplyScalesOnSize(size);

m_LastScaledSize = scaledSize;
return scaledSize;
}
Expand All @@ -526,6 +527,9 @@ internal Vector2Int ApplyScalesOnSize(Vector2Int size, Vector2 scales)
scaledSize.y += (1 & scaledSize.y);
}

scaledSize.x = Math.Min(scaledSize.x, size.x);
scaledSize.y = Math.Min(scaledSize.y, size.y);

return scaledSize;
}

Expand Down
1 change: 1 addition & 0 deletions com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed CustomPassUtils.Copy function not working on depth buffers.
- Fixed a nullref when binding a RTHandle allocated from a RenderTextureIdentifier with CoreUtils.SetRenderTarget.
- Fixed off by 1 error when calculating the depth pyramid texture size when DRS is on.
- Fixed CPU performance on DLSS, avoiding to recreate state whenever a target can fall into the safe min/max resolution specified by the system.

### Changed
- Changed Window/Render Pipeline/HD Render Pipeline Wizard to Window/Rendering/HDRP Wizard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ void ConfigureKeywords(bool enableBakeShadowMask, HDCamera hdCamera, CommandBuff
bool useOptimalSettings = hdCam.deepLearningSuperSamplingUseCustomAttributes
? hdCam.deepLearningSuperSamplingUseOptimalSettings
: m_Asset.currentPlatformRenderPipelineSettings.dynamicResolutionSettings.DLSSUseOptimalSettings;
m_DLSSPass.SetupAutomaticDRSScaling(useOptimalSettings, camera, xrPass, ref outDrsSettings);
m_DLSSPass.SetupDRSScaling(useOptimalSettings, camera, xrPass, ref outDrsSettings);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,10 @@ public void BeginFrame(HDCamera hdCamera)
#endif
}

public void SetupAutomaticDRSScaling(bool enabled, Camera camera, XRPass xrPass, ref GlobalDynamicResolutionSettings dynamicResolutionSettings)
public void SetupDRSScaling(bool enableAutomaticSettings, Camera camera, XRPass xrPass, ref GlobalDynamicResolutionSettings dynamicResolutionSettings)
{
#if ENABLE_NVIDIA && ENABLE_NVIDIA_MODULE
InternalNVIDIASetupAutomaticDRSScaling(enabled, camera, xrPass, ref dynamicResolutionSettings);
InternalNVIDIASetupDRSScaling(enableAutomaticSettings, camera, xrPass, ref dynamicResolutionSettings);
#endif
}

Expand Down Expand Up @@ -288,6 +288,11 @@ private struct OptimalSettingsRequest
public NVIDIA.DLSSQuality quality;
public Rect viewport;
public NVIDIA.OptimalDLSSSettingsData optimalSettings;
public bool CanFit(DLSSPass.Resolution rect)
{
return rect.width >= optimalSettings.minWidth && rect.height >= optimalSettings.minHeight
&& rect.width <= optimalSettings.maxWidth && rect.height <= optimalSettings.maxHeight;
}
}

private static bool IsOptimalSettingsValid(in NVIDIA.OptimalDLSSSettingsData optimalSettings)
Expand All @@ -306,11 +311,12 @@ private class ViewState
private NVIDIA.GraphicsDevice m_Device;
private DlssViewData m_Data = new DlssViewData();
private bool m_UsingOptimalSettings = false;
private bool m_OptimalSettingsRequested = false;
private bool m_UseAutomaticSettings = false;
private DLSSPass.Resolution m_BackbufferRes;
private OptimalSettingsRequest m_OptimalSettingsRequest = new OptimalSettingsRequest();

public NVIDIA.DLSSContext DLSSContext { get { return m_DlssContext; } }
public bool RequestedOptimalSettings { get { return m_OptimalSettingsRequested; } }
public bool useAutomaticSettings { get { return m_UseAutomaticSettings; } }
public OptimalSettingsRequest OptimalSettingsRequestData { get { return m_OptimalSettingsRequest; } }

public ViewState(NVIDIA.GraphicsDevice device)
Expand All @@ -319,22 +325,22 @@ public ViewState(NVIDIA.GraphicsDevice device)
m_DlssContext = null;
}

public void RequestUseOptimalSetting(NVIDIA.DLSSQuality quality, Rect viewport, in NVIDIA.OptimalDLSSSettingsData optimalSettings)
public void RequestUseAutomaticSettings(bool useAutomaticSettings, NVIDIA.DLSSQuality quality, Rect viewport, in NVIDIA.OptimalDLSSSettingsData optimalSettings)
{
m_OptimalSettingsRequested = true;
m_UseAutomaticSettings = useAutomaticSettings;
m_OptimalSettingsRequest.quality = quality;
m_OptimalSettingsRequest.viewport = viewport;
m_OptimalSettingsRequest.optimalSettings = optimalSettings;
}

public void ClearOptimalSettings()
public void ClearAutomaticSettings()
{
m_OptimalSettingsRequested = false;
m_UseAutomaticSettings = false;
}

private bool ShouldUseOptimalSettings()
private bool ShouldUseAutomaticSettings()
{
if (!m_OptimalSettingsRequested || m_DlssContext == null)
if (!m_UseAutomaticSettings || m_DlssContext == null)
return false;

return m_DlssContext.initData.quality == m_OptimalSettingsRequest.quality
Expand All @@ -347,16 +353,17 @@ private bool ShouldUseOptimalSettings()
in DlssViewData viewData,
CommandBuffer cmdBuffer)
{
bool shouldUseOptimalSettings = ShouldUseOptimalSettings();
bool shouldUseOptimalSettings = ShouldUseAutomaticSettings();
bool isNew = false;
if (viewData.outputRes != m_Data.outputRes ||
(viewData.inputRes != m_Data.inputRes && !m_UsingOptimalSettings) ||
(viewData.CanFitInput(m_Data.inputRes) && m_UsingOptimalSettings) ||
(viewData.inputRes.width > m_BackbufferRes.width || viewData.inputRes.height > m_BackbufferRes.height) ||
(viewData.inputRes != m_BackbufferRes && !m_OptimalSettingsRequest.CanFit(viewData.inputRes)) ||
viewData.perfQuality != m_Data.perfQuality ||
m_DlssContext == null ||
shouldUseOptimalSettings != m_UsingOptimalSettings)
{
isNew = true;
m_BackbufferRes = viewData.inputRes;

if (m_DlssContext != null)
{
Expand All @@ -369,8 +376,8 @@ private bool ShouldUseOptimalSettings()
settings.SetFlag(NVIDIA.DLSSFeatureFlags.MVLowRes, true);
settings.SetFlag(NVIDIA.DLSSFeatureFlags.DepthInverted, true);
settings.SetFlag(NVIDIA.DLSSFeatureFlags.DoSharpening, true);
settings.inputRTWidth = viewData.inputRes.width;
settings.inputRTHeight = viewData.inputRes.height;
settings.inputRTWidth = m_BackbufferRes.width;
settings.inputRTHeight = m_BackbufferRes.height;
settings.outputRTWidth = viewData.outputRes.width;
settings.outputRTHeight = viewData.outputRes.height;
settings.quality = viewData.perfQuality;
Expand Down Expand Up @@ -449,12 +456,12 @@ public bool IsAlive()
return m_CamReference.TryGetTarget(out _);
}

public void ClearOptimalSettings()
public void ClearAutomaticSettings()
{
if (m_Views == null)
return;
foreach (var v in m_Views)
v.ClearOptimalSettings();
v.ClearAutomaticSettings();
}

public void SubmitCommands(
Expand Down Expand Up @@ -578,7 +585,7 @@ private float ScaleFn()
return 100.0f;

var viewState = cameraState.ViewStates[0];
if (!viewState.RequestedOptimalSettings)
if (!viewState.useAutomaticSettings)
return 100.0f;

var optimalSettings = viewState.OptimalSettingsRequestData.optimalSettings;
Expand All @@ -588,7 +595,7 @@ private float ScaleFn()
return Mathf.Min(suggestedPercentageX, suggestedPercentageY) * 100.0f;
}

private void InternalNVIDIASetupAutomaticDRSScaling(bool enabled, Camera camera, XRPass xrPass, ref GlobalDynamicResolutionSettings dynamicResolutionSettings)
private void InternalNVIDIASetupDRSScaling(bool enableAutomaticSettings, Camera camera, XRPass xrPass, ref GlobalDynamicResolutionSettings dynamicResolutionSettings)
{
if (m_Device == null)
return;
Expand All @@ -604,38 +611,33 @@ private void InternalNVIDIASetupAutomaticDRSScaling(bool enabled, Camera camera,
if (cameraState.ViewStates[0].DLSSContext == null)
return;

if (!enabled)
{
cameraState.ClearOptimalSettings();
}
else
var usedQuality = cameraState.ViewStates[0].DLSSContext.initData.quality;
Rect finalViewport = xrPass != null && xrPass.enabled ? xrPass.GetViewport() : new Rect(camera.pixelRect.x, camera.pixelRect.y, camera.pixelWidth, camera.pixelHeight);
NVIDIA.OptimalDLSSSettingsData optimalSettings = new NVIDIA.OptimalDLSSSettingsData();
m_Device.GetOptimalSettings((uint)finalViewport.width, (uint)finalViewport.height, usedQuality, out optimalSettings);

foreach (var view in cameraState.ViewStates)
{
var usedQuality = cameraState.ViewStates[0].DLSSContext.initData.quality;
Rect finalViewport = xrPass != null && xrPass.enabled ? xrPass.GetViewport() : new Rect(camera.pixelRect.x, camera.pixelRect.y, camera.pixelWidth, camera.pixelHeight);
NVIDIA.OptimalDLSSSettingsData optimalSettings = new NVIDIA.OptimalDLSSSettingsData();
if (view == null)
continue;

if (!m_Device.GetOptimalSettings((uint)finalViewport.width, (uint)finalViewport.height, usedQuality, out optimalSettings))
{
cameraState.ClearOptimalSettings();
return;
}
view.RequestUseAutomaticSettings(enableAutomaticSettings, usedQuality, finalViewport, optimalSettings);
}

if (IsOptimalSettingsValid(optimalSettings))
if (enableAutomaticSettings)
{
if (IsOptimalSettingsValid(optimalSettings) && enableAutomaticSettings)
{
dynamicResolutionSettings.maxPercentage = Mathf.Min((float)optimalSettings.maxWidth / finalViewport.width, (float)optimalSettings.maxHeight / finalViewport.height) * 100.0f;
dynamicResolutionSettings.minPercentage = Mathf.Max((float)optimalSettings.minWidth / finalViewport.width, (float)optimalSettings.minHeight / finalViewport.height) * 100.0f;
m_SelectedCameraKey = cameraKey;
DynamicResolutionHandler.SetSystemDynamicResScaler(ScaleFn, DynamicResScalePolicyType.ReturnsPercentage);
DynamicResolutionHandler.SetActiveDynamicScalerSlot(DynamicResScalerSlot.System);
}

foreach (var view in cameraState.ViewStates)
{
if (view == null)
continue;

view.RequestUseOptimalSetting(usedQuality, finalViewport, optimalSettings);
}
}
else
{
cameraState.ClearAutomaticSettings();
}
}

Expand Down Expand Up @@ -690,6 +692,7 @@ private void InternalNVIDIARender(in DLSSPass.Parameters parameters, DLSSPass.Ca

dlssViewData.inputRes = new Resolution() { width = (uint)parameters.hdCamera.actualWidth, height = (uint)parameters.hdCamera.actualHeight };
dlssViewData.outputRes = new Resolution() { width = (uint)DynamicResolutionHandler.instance.finalViewport.x, height = (uint)DynamicResolutionHandler.instance.finalViewport.y };

dlssViewData.jitterX = -parameters.hdCamera.taaJitter.x;
dlssViewData.jitterY = -parameters.hdCamera.taaJitter.y;
dlssViewData.reset = parameters.hdCamera.isFirstFrame;
Expand Down

0 comments on commit ad100f7

Please sign in to comment.