From d65d009ff70ad836204152e580e5911a77cea4c3 Mon Sep 17 00:00:00 2001 From: Robin Date: Tue, 9 Feb 2021 09:56:46 +0000 Subject: [PATCH] Fix for dynamic resolution and MSVO causing a higher peak VRAM usage 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 --- com.unity.postprocessing/CHANGELOG.md | 5 + .../Runtime/Effects/MultiScaleVO.cs | 122 ++++++++++-------- com.unity.postprocessing/package.json | 2 +- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/com.unity.postprocessing/CHANGELOG.md b/com.unity.postprocessing/CHANGELOG.md index 4547876011d..e4328df5070 100644 --- a/com.unity.postprocessing/CHANGELOG.md +++ b/com.unity.postprocessing/CHANGELOG.md @@ -4,6 +4,11 @@ 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.3] - 2021-02-09 + +### Fixed +- 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.2] - 2020-12-08 ### Fixed diff --git a/com.unity.postprocessing/PostProcessing/Runtime/Effects/MultiScaleVO.cs b/com.unity.postprocessing/PostProcessing/Runtime/Effects/MultiScaleVO.cs index 7eb4ffdeb7f..e475673bc7b 100644 --- a/com.unity.postprocessing/PostProcessing/Runtime/Effects/MultiScaleVO.cs +++ b/com.unity.postprocessing/PostProcessing/Runtime/Effects/MultiScaleVO.cs @@ -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]; @@ -74,13 +76,18 @@ 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, @@ -88,6 +95,9 @@ void Alloc(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, 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, @@ -95,13 +105,18 @@ void Alloc(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat format, }, 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, @@ -109,6 +124,9 @@ void AllocArray(CommandBuffer cmd, int id, MipLevel size, RenderTextureFormat fo 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, @@ -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); @@ -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); } } @@ -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; diff --git a/com.unity.postprocessing/package.json b/com.unity.postprocessing/package.json index 42916ac9d0b..7ab4bed0443 100644 --- a/com.unity.postprocessing/package.json +++ b/com.unity.postprocessing/package.json @@ -1,6 +1,6 @@ { "name": "com.unity.postprocessing", - "version": "3.0.2", + "version": "3.0.3", "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.",