Skip to content

Fix to reduce the amount of allocations required when using MSVO and Dynamic Resolution #3442

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

Merged
merged 3 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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