Skip to content

Commit

Permalink
Fix for dynamic resolution and MSVO causing a higher peak VRAM usage …
Browse files Browse the repository at this point in the history
…and possible fragmentation issues when the dynamic scale is changed regularly. Brought across from https://github.com/Unity-Technologies/PostProcessing/compare/v2-msvo-dynamic-res-fix (#3442)

Co-authored-by: Thomas <chman.a11w@gmail.com>
Co-authored-by: sebastienlagarde <sebastien@unity3d.com>
  • Loading branch information
3 people authored Feb 25, 2021
1 parent c27d45b commit 3806572
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 51 deletions.
1 change: 1 addition & 0 deletions com.unity.postprocessing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Fixed
- Fix for issue thrown upon unloading a scene from an AssetBundle (case 1262826)
- Fix for MSVO when used with dynamic resolution reallocating temporary render targets whenever the dynamic resolution scale was changed which could cause a higher peak VRAM usage and fragmentation (Case 1285605). Temporary targets will now use dynamic scaling as well to solve this. Please note there is a bug in Unity that breaks this fix (case 1285577) To make use of dynamic resolution and MSVO please use Unity 2019.4.19f1, 2020.2.2f1, 2021.1.0a9 or later.

## [3.0.3] - 2021-02-19

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ enum Pass
readonly float[] m_InvThicknessTable = new float[12];
readonly float[] m_SampleWeightTable = new float[12];

readonly int[] m_Widths = new int[7];
readonly int[] m_Heights = new int[7];
// Scaled dimensions used with dynamic resolution
readonly int[] m_ScaledWidths = new int[7];
readonly int[] m_ScaledHeights = new int[7];
Expand Down Expand Up @@ -74,41 +76,57 @@ public void SetResources(PostProcessResources resources)
m_Resources = resources;
}

void Alloc(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, bool uav)
void Alloc(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, bool uav, bool dynamicScale)
{
int sizeId = (int)size;
cmd.GetTemporaryRT(id, new RenderTextureDescriptor
{
#if UNITY_2019_4_OR_NEWER
width = m_Widths[sizeId],
height = m_Heights[sizeId],
#else
width = m_ScaledWidths[sizeId],
height = m_ScaledHeights[sizeId],
#endif
colorFormat = format,
depthBufferBits = 0,
volumeDepth = 1,
autoGenerateMips = false,
msaaSamples = 1,
#if UNITY_2019_2_OR_NEWER
mipCount = 1,
#endif
#if UNITY_2019_4_OR_NEWER
useDynamicScale = dynamicScale,
#endif
enableRandomWrite = uav,
dimension = TextureDimension.Tex2D,
sRGB = false
}, FilterMode.Point);
}

void AllocArray(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, bool uav)
void AllocArray(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, bool uav, bool dynamicScale)
{
int sizeId = (int)size;
cmd.GetTemporaryRT(id, new RenderTextureDescriptor
{
#if UNITY_2019_4_OR_NEWER
width = m_Widths[sizeId],
height = m_Heights[sizeId],
#else
width = m_ScaledWidths[sizeId],
height = m_ScaledHeights[sizeId],
#endif
colorFormat = format,
depthBufferBits = 0,
volumeDepth = 16,
autoGenerateMips = false,
msaaSamples = 1,
#if UNITY_2019_2_OR_NEWER
mipCount = 1,
#endif
#if UNITY_2019_4_OR_NEWER
useDynamicScale = dynamicScale,
#endif
enableRandomWrite = uav,
dimension = TextureDimension.Tex2DArray,
Expand Down Expand Up @@ -152,24 +170,26 @@ Vector3 GetSizeArray(MipLevel mip)
public void GenerateAOMap(CommandBuffer cmd, Camera camera, RenderTargetIdentifier destination, RenderTargetIdentifier? depthMap, bool invert, bool isMSAA)
{
// Base size
m_Widths[0] = m_ScaledWidths[0] = camera.pixelWidth * (RuntimeUtilities.isSinglePassStereoEnabled ? 2 : 1);
m_Heights[0] = m_ScaledHeights[0] = camera.pixelHeight;
#if UNITY_2017_3_OR_NEWER
m_ScaledWidths[0] = camera.scaledPixelWidth * (RuntimeUtilities.isSinglePassStereoEnabled ? 2 : 1);
m_ScaledHeights[0] = camera.scaledPixelHeight;
#else
m_ScaledWidths[0] = camera.pixelWidth * (RuntimeUtilities.isSinglePassStereoEnabled ? 2 : 1);
m_ScaledHeights[0] = camera.pixelHeight;
#endif

float widthScalingFactor = ScalableBufferManager.widthScaleFactor;
float heightScalingFactor = ScalableBufferManager.heightScaleFactor;
// L1 -> L6 sizes
for (int i = 1; i < 7; i++)
{
int div = 1 << i;
m_ScaledWidths[i] = (m_ScaledWidths[0] + (div - 1)) / div;
m_ScaledHeights[i] = (m_ScaledHeights[0] + (div - 1)) / div;
m_Widths[i] = (m_Widths[0] + (div - 1)) / div;
m_Heights[i] = (m_Heights[0] + (div - 1)) / div;
m_ScaledWidths[i] = Mathf.CeilToInt(m_Widths[i] * widthScalingFactor);
m_ScaledHeights[i] = Mathf.CeilToInt(m_Heights[i] * heightScalingFactor);
}

// Allocate temporary textures
PushAllocCommands(cmd, isMSAA);
PushAllocCommands(cmd, isMSAA, camera);

// Render logic
PushDownsampleCommands(cmd, camera, depthMap, isMSAA);
Expand All @@ -189,53 +209,53 @@ public void GenerateAOMap(CommandBuffer cmd, Camera camera, RenderTargetIdentifi
PushReleaseCommands(cmd);
}

void PushAllocCommands(CommandBuffer cmd, bool isMSAA)
void PushAllocCommands(CommandBuffer cmd, bool isMSAA, Camera camera)
{
if (isMSAA)
{
Alloc(cmd, ShaderIDs.LinearDepth, MipLevel.Original, RenderTextureFormat.RGHalf, true);

Alloc(cmd, ShaderIDs.LowDepth1, MipLevel.L1, RenderTextureFormat.RGFloat, true);
Alloc(cmd, ShaderIDs.LowDepth2, MipLevel.L2, RenderTextureFormat.RGFloat, true);
Alloc(cmd, ShaderIDs.LowDepth3, MipLevel.L3, RenderTextureFormat.RGFloat, true);
Alloc(cmd, ShaderIDs.LowDepth4, MipLevel.L4, RenderTextureFormat.RGFloat, true);

AllocArray(cmd, ShaderIDs.TiledDepth1, MipLevel.L3, RenderTextureFormat.RGHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth2, MipLevel.L4, RenderTextureFormat.RGHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth3, MipLevel.L5, RenderTextureFormat.RGHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth4, MipLevel.L6, RenderTextureFormat.RGHalf, true);

Alloc(cmd, ShaderIDs.Occlusion1, MipLevel.L1, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.Occlusion2, MipLevel.L2, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.Occlusion3, MipLevel.L3, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.Occlusion4, MipLevel.L4, RenderTextureFormat.RG16, true);

Alloc(cmd, ShaderIDs.Combined1, MipLevel.L1, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.Combined2, MipLevel.L2, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.Combined3, MipLevel.L3, RenderTextureFormat.RG16, true);
Alloc(cmd, ShaderIDs.LinearDepth, MipLevel.Original, RenderTextureFormat.RGHalf, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.LowDepth1, MipLevel.L1, RenderTextureFormat.RGFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth2, MipLevel.L2, RenderTextureFormat.RGFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth3, MipLevel.L3, RenderTextureFormat.RGFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth4, MipLevel.L4, RenderTextureFormat.RGFloat, true, camera.allowDynamicResolution);

AllocArray(cmd, ShaderIDs.TiledDepth1, MipLevel.L3, RenderTextureFormat.RGHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth2, MipLevel.L4, RenderTextureFormat.RGHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth3, MipLevel.L5, RenderTextureFormat.RGHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth4, MipLevel.L6, RenderTextureFormat.RGHalf, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.Occlusion1, MipLevel.L1, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion2, MipLevel.L2, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion3, MipLevel.L3, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion4, MipLevel.L4, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.Combined1, MipLevel.L1, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Combined2, MipLevel.L2, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Combined3, MipLevel.L3, RenderTextureFormat.RG16, true, camera.allowDynamicResolution);
}
else
{
Alloc(cmd, ShaderIDs.LinearDepth, MipLevel.Original, RenderTextureFormat.RHalf, true);

Alloc(cmd, ShaderIDs.LowDepth1, MipLevel.L1, RenderTextureFormat.RFloat, true);
Alloc(cmd, ShaderIDs.LowDepth2, MipLevel.L2, RenderTextureFormat.RFloat, true);
Alloc(cmd, ShaderIDs.LowDepth3, MipLevel.L3, RenderTextureFormat.RFloat, true);
Alloc(cmd, ShaderIDs.LowDepth4, MipLevel.L4, RenderTextureFormat.RFloat, true);

AllocArray(cmd, ShaderIDs.TiledDepth1, MipLevel.L3, RenderTextureFormat.RHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth2, MipLevel.L4, RenderTextureFormat.RHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth3, MipLevel.L5, RenderTextureFormat.RHalf, true);
AllocArray(cmd, ShaderIDs.TiledDepth4, MipLevel.L6, RenderTextureFormat.RHalf, true);

Alloc(cmd, ShaderIDs.Occlusion1, MipLevel.L1, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.Occlusion2, MipLevel.L2, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.Occlusion3, MipLevel.L3, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.Occlusion4, MipLevel.L4, RenderTextureFormat.R8, true);

Alloc(cmd, ShaderIDs.Combined1, MipLevel.L1, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.Combined2, MipLevel.L2, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.Combined3, MipLevel.L3, RenderTextureFormat.R8, true);
Alloc(cmd, ShaderIDs.LinearDepth, MipLevel.Original, RenderTextureFormat.RHalf, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.LowDepth1, MipLevel.L1, RenderTextureFormat.RFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth2, MipLevel.L2, RenderTextureFormat.RFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth3, MipLevel.L3, RenderTextureFormat.RFloat, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.LowDepth4, MipLevel.L4, RenderTextureFormat.RFloat, true, camera.allowDynamicResolution);

AllocArray(cmd, ShaderIDs.TiledDepth1, MipLevel.L3, RenderTextureFormat.RHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth2, MipLevel.L4, RenderTextureFormat.RHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth3, MipLevel.L5, RenderTextureFormat.RHalf, true, camera.allowDynamicResolution);
AllocArray(cmd, ShaderIDs.TiledDepth4, MipLevel.L6, RenderTextureFormat.RHalf, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.Occlusion1, MipLevel.L1, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion2, MipLevel.L2, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion3, MipLevel.L3, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Occlusion4, MipLevel.L4, RenderTextureFormat.R8, true, camera.allowDynamicResolution);

Alloc(cmd, ShaderIDs.Combined1, MipLevel.L1, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Combined2, MipLevel.L2, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
Alloc(cmd, ShaderIDs.Combined3, MipLevel.L3, RenderTextureFormat.R8, true, camera.allowDynamicResolution);
}
}

Expand All @@ -254,7 +274,7 @@ void PushDownsampleCommands(CommandBuffer cmd, Camera camera, RenderTargetIdenti
// buffer (it's only available in some specific situations).
if (!RuntimeUtilities.IsResolvedDepthAvailable(camera))
{
Alloc(cmd, ShaderIDs.DepthCopy, MipLevel.Original, RenderTextureFormat.RFloat, false);
Alloc(cmd, ShaderIDs.DepthCopy, MipLevel.Original, RenderTextureFormat.RFloat, false, camera.allowDynamicResolution);
depthMapId = new RenderTargetIdentifier(ShaderIDs.DepthCopy);
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, depthMapId, m_PropertySheet, (int)Pass.DepthCopy);
needDepthMapRelease = true;
Expand Down
1 change: 1 addition & 0 deletions com.unity.postprocessing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "3.1.0",
"displayName": "Post Processing",
"unity": "2019.4",
"unityRelease": "19f1",
"description": "The post-processing stack (v2) comes with a collection of effects and image filters you can apply to your cameras to improve the visuals of your games.",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
Expand Down

0 comments on commit 3806572

Please sign in to comment.