Skip to content
This repository has been archived by the owner on Nov 30, 2020. It is now read-only.

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

Draft
wants to merge 5 commits into
base: v2
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [3.0.1] - 2020-10-16
### Fixed
- Fix for MSVO when used with dynamic resolution reallocating temp render targets whenever the dynamic resolution scale was changed. Now those temp targets will use dynamic scaling as well. This will require a matching fix in Unity to work correctly (ADD COMPATIBLE VERSIONS HERE). (case XXXXXX).

## [3.0.0] - 2020-10-13

### Fixed
Expand Down
128 changes: 76 additions & 52 deletions PostProcessing/Runtime/Effects/MultiScaleVO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ enum Pass
readonly float[] m_InvThicknessTable = new float[12];
readonly float[] m_SampleWeightTable = new float[12];

// Scaled dimensions used with dynamic resolution
// Unscaled dimensions used for allocating targets that might scale themselves.
readonly int[] m_Widths = new int[7];
readonly int[] m_Heights = new int[7];

// Scaled dimensions adjusted for the current dynamic resolution scale
readonly int[] m_ScaledWidths = new int[7];
readonly int[] m_ScaledHeights = new int[7];

Expand Down Expand Up @@ -74,41 +78,59 @@ 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 +174,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
// Adjust the scaled dimensions based off the dynamic resolution resolution used at the moment.
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

// L1 -> L6 sizes
for (int i = 1; i < 7; i++)
{
int div = 1 << i;
m_Widths[i] = (m_Widths[0] + (div - 1)) / div;
m_Heights[i] = (m_Heights[0] + (div - 1)) / div;
m_ScaledWidths[i] = (m_ScaledWidths[0] + (div - 1)) / div;
m_ScaledHeights[i] = (m_ScaledHeights[0] + (div - 1)) / div;
}

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

// Render logic
PushDownsampleCommands(cmd, camera, depthMap, isMSAA);
Expand All @@ -189,53 +213,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 +278,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 Expand Up @@ -463,9 +487,9 @@ void PreparePropertySheet(PostProcessRenderContext context)
void CheckAOTexture(PostProcessRenderContext context)
{
bool AOUpdateNeeded = m_AmbientOnlyAO == null || !m_AmbientOnlyAO.IsCreated() || m_AmbientOnlyAO.width != context.width || m_AmbientOnlyAO.height != context.height;
#if UNITY_2017_3_OR_NEWER
#if UNITY_2017_3_OR_NEWER
AOUpdateNeeded = AOUpdateNeeded || m_AmbientOnlyAO.useDynamicScale != context.camera.allowDynamicResolution;
#endif
#endif
if (AOUpdateNeeded)
{
RuntimeUtilities.Destroy(m_AmbientOnlyAO);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.unity.postprocessing",
"version": "3.0.0",
"version": "3.0.1",
"displayName": "Post Processing",
"unity": "2018.4",
"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.",
Expand Down