New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improving DLSS cpu load, and not recreating DLSS state every change of res #5231
Conversation
Hi! This comment will help you figure out which jobs to run before merging your PR. The suggestions are dynamic based on what files you have changed. HDRP SRP Core Depending on the scope of your PR, you may need to run more jobs than what has been suggested. Please speak to your lead or a Graphics SDET (#devs-graphics-automation) if you are unsure. |
c603ca7
to
e874a3a
Compare
actualWidth = scaledSize.x; | ||
actualHeight = scaledSize.y; | ||
//ensure that the scale is within and we dont round up an extra pixel | ||
actualWidth = Math.Min(scaledSize.x, actualWidth); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels to me this should be done inside DynamicResolutionHandler.instance.GetScaledSize itself, I cannot think of a scenario in which we want to exceed.
Moreover if at some point we modify the dynamic resolution to scale up as well, it'd be good to have it self contained in the handler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah its possible since the drs handler is aware of the viewport size.
Just need to be more careful with this though since now we are making this function dependant on a final viewport size and test a bit more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh no I mean clamping to the thing that is passed to GetScaledSize (in this case is actualWidth/Height)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah! right. Yes this should be easy
com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DLSSPass.cs
Outdated
Show resolved
Hide resolved
For my curiosity: How inclusive are those "optimal settings"? Is there a threshold in which we thrash back and forth the recreation? |
e874a3a
to
353ade3
Compare
@FrancescoC-unity Depending on the quality, it can go down to 20% (for the high performance settings) up to 50% (for the high quality settings). |
@@ -501,6 +501,10 @@ public Vector2Int GetScaledSize(Vector2Int size) | |||
} | |||
|
|||
Vector2Int scaledSize = ApplyScalesOnSize(size); | |||
|
|||
scaledSize.x = Math.Min(scaledSize.x, size.x); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should do this in ApplyScalesOnSize though as that is public API too, specifically this variant :
Vector2Int ApplyScalesOnSize(Vector2Int size, Vector2 scales)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, for now, I quickly tested and can still repro the crash.
I've narrowed the fact that it's DX12 related (doesn't happen in vulkan or dx11).
@kecho managed to repro it so hopefully we'll be able to find the cause.
in the meantime, there's a crash folder zipped, if needed.
Crash_2021-07-27_151018460.zip
@remi-chapelain for now I have removed the fogbugz on this PR, and instead keep this PR as an optimization. So as long as DLSS is running well on this PR we should still pursue it. |
@@ -421,8 +421,10 @@ public void Update(GlobalDynamicResolutionSettings settings, Action OnResolution | |||
if (!m_ForceSoftwareFallback && type == DynamicResolutionType.Hardware) | |||
{ | |||
hardwareResolutionChanged = FlushScalableBufferManagerState(); | |||
if (ScalableBufferManager.widthScaleFactor != m_PrevHWScaleWidth || | |||
ScalableBufferManager.heightScaleFactor != m_PrevHWScaleHeight) | |||
float sfw = ScalableBufferManager.widthScaleFactor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is a no-op right? I don't see the advantage as I tend to like more verbose naming vs acronyms, but am not opposed. However, if it is for clarity let me be an anal nitpicker and either we have sfw and sfh or wsf and hsf, now is a bit of a mixup of names.,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is left over on my side! i was debugging stuff. Good catch!
@@ -391,7 +391,7 @@ public void Update(GlobalDynamicResolutionSettings settings, Action OnResolution | |||
{ | |||
ProcessSettings(settings); | |||
|
|||
if (!m_Enabled && !s_ActiveInstanceDirty) | |||
if (!m_Enabled || !s_ActiveInstanceDirty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what this change is doing?
So s_ActiveInstanceDirty is determining whether we changed anything (is set to false at the end of this), so essentially this is going to call the update every 2 frames instead of every frame which of course is not what we want to do.
Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have been an or conditional.
Basically dont run this function if we already called it in the frame.
The reason is that we have 2 loops for cameras within the same frame.
Each loop calls UpdateAndUseCamera. So a camera calls Update() twice. But we only need to flush all the settings once per frame.
ClearSelectedCamera gets called at the end of the frame and sets this dirty flag to true.
THe problem is that this was false, it should be true. This fixes some crazy artifacting when resizing Hardware resolution scaler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha! I missed the
ClearSelectedCamera gets called at the end of the frame and sets this dirty flag to true.
part.
Makes all sense.
73e7729
to
a82c584
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't fix the crash (reported here) but after some quick tests on the template, it seems to improve slightly performance around 10% give or take.
I also tested on Vulkan, DX11 and DX12 to be sure that it didn't cause any issues there.
Indeed. The crash will be fixed at a later point. I will do a debug session with @remi-chapelain since we can only repro it on his mahcine. This however is a good change for performance improvements. |
e34b39b
to
09ce4aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to the slight improvement, this PR fixes this issue (#1354184)
… 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
09ce4aa
to
c7f674d
Compare
Purpose of this PR
DLSS was recreating state every change of resolution for DRS. This was a bit of an oversight, caused by not checking the min and max resolution that DLSS suggest
Turns out that we should always query for the min and max resolution regardless if auto parameters are enabeld or not. This range is the only range were we are allowed to utilize hot DRS scaling. Otherwise, if we request outside this range, we must in turn recrete the DRS feature state.
The non technical summary: we optimized CPU usage and straining of system. DRS should run much smoother.
Fixed also a problem were if the viewport is odd size of pixels, the DRS scaler would return a 1 pixel extra. So to fix this, clamped the actualWidth/actualHeight post resolution.
Testing status
Comments to reviewers
I renamed some functions but the jist of the change is that we now call GetOptimalSettings every frame, use the safe ranges for DRS, and optionally use the sharpness / autoscaler on the setting.