diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx index 8681e95..0e86960 100644 Binary files a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx and b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx differ diff --git a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs index ce6c51a..06c66c3 100644 --- a/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs +++ b/Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs @@ -13,13 +13,14 @@ namespace UnityEngine.Rendering.PostProcessing private IntPtr _dispatchParamsBuffer; private RenderTexture _inputColor; - private RenderTexture _inputDepth; - private RenderTexture _inputMotionVectors; + private readonly RenderTexture[] _inputDepth = new RenderTexture[2]; + private readonly RenderTexture[] _inputMotionVectors = new RenderTexture[2]; private RenderTexture _outputColor; private Texture2D _outputIntermediate; private bool _pluginInitialized; private bool _contextInitialized; + private uint _frameCount; public override void CreateContext(PostProcessRenderContext context, Upscaling config) { @@ -37,10 +38,11 @@ namespace UnityEngine.Rendering.PostProcessing initParams.displayHeight = (uint)config.UpscaleSize.y; initParams.maxRenderWidth = (uint)config.MaxRenderSize.x; initParams.maxRenderHeight = (uint)config.MaxRenderSize.y; + initParams.autoKeepCopies = 0u; // We use double buffered depth and motion vector copies created by Unity CreateRenderTexture(ref _inputColor, "PSSR Input Color", config.MaxRenderSize, context.sourceFormat, true); - CreateRenderTexture(ref _inputDepth, "PSSR Input Depth", config.MaxRenderSize, GraphicsFormat.R32_SFloat, true); // TODO: this texture won't have tile mode kDepth, meaning PSSR doesn't detect it correctly. Is this a problem? - CreateRenderTexture(ref _inputMotionVectors, "PSSR Input Motion Vectors", config.MaxRenderSize, GraphicsFormat.R16G16_SFloat, true); + CreateRenderTextureArray( _inputDepth, "PSSR Input Depth", config.MaxRenderSize, GraphicsFormat.R32_SFloat, true); + CreateRenderTextureArray(_inputMotionVectors, "PSSR Input Motion Vectors", config.MaxRenderSize, GraphicsFormat.R16G16_SFloat, true); CreateRenderTexture(ref _outputColor, "PSSR Output Color", config.UpscaleSize, RenderTextureFormat.RGB111110Float); if (PSSRPlugin.CreatePssrContext(ref initParams, out IntPtr outputColorTexturePtr) >= 0 && outputColorTexturePtr != IntPtr.Zero) @@ -69,7 +71,8 @@ namespace UnityEngine.Rendering.PostProcessing } DestroyRenderTexture(ref _outputColor); - DestroyRenderTexture(ref _inputDepth); + DestroyRenderTextureArray(_inputMotionVectors); + DestroyRenderTextureArray(_inputDepth); DestroyRenderTexture(ref _inputColor); if (_dispatchParamsBuffer != IntPtr.Zero) @@ -95,24 +98,46 @@ namespace UnityEngine.Rendering.PostProcessing } cmd.BeginSample("PSSR"); + + if (config.Reset || _frameCount == 0) + { + cmd.SetRenderTarget(_inputDepth[0]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_inputDepth[1]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_inputMotionVectors[0]); + cmd.ClearRenderTarget(false, true, Color.clear); + cmd.SetRenderTarget(_inputMotionVectors[1]); + cmd.ClearRenderTarget(false, true, Color.clear); + } + + int frameIndex = (int)(_frameCount++ % 2); - // TODO: if PSSR needs a copy of the previous depth and motion vectors anyway, why not just double-buffer those resources ourselves and make good use of these otherwise dumb copies? - PrepareInputs(cmd, context, config, _inputColor, _inputDepth, _inputMotionVectors); + // We need to provide copies of the previous depth and motion vector buffers anyway, so we can turn this otherwise wasteful copying into a benefit + PrepareInputs(cmd, context, config, _inputColor, _inputDepth[frameIndex], _inputMotionVectors[frameIndex]); + + Texture reactiveMask = config.reactiveMask; + if (config.autoGenerateReactiveMask || config.autoGenerateTransparencyAndComposition) + { + reactiveMask = GenerateReactiveMask(cmd, context, config); + } var flags = PSSRPlugin.OptionFlags.None; if (SystemInfo.usesReversedZBuffer) flags |= PSSRPlugin.OptionFlags.ReverseDepth; if (config.exposureSource == Upscaling.ExposureSource.Auto) flags |= PSSRPlugin.OptionFlags.AutoExposure; _dispatchParams.color = ToNativePtr(_inputColor); - _dispatchParams.depth = ToNativePtr(_inputDepth); - _dispatchParams.motionVectors = ToNativePtr(_inputMotionVectors); + _dispatchParams.depth = ToNativePtr(_inputDepth[frameIndex]); + _dispatchParams.prevDepth = ToNativePtr(_inputDepth[frameIndex ^ 1]); + _dispatchParams.motionVectors = ToNativePtr(_inputMotionVectors[frameIndex]); + _dispatchParams.prevMotionVectors = ToNativePtr(_inputMotionVectors[frameIndex ^ 1]); _dispatchParams.exposure = ToNativePtr(config.exposureSource switch { Upscaling.ExposureSource.Manual when config.exposure != null => config.exposure, Upscaling.ExposureSource.Unity => context.autoExposureTexture, _ => null, }); - _dispatchParams.reactiveMask = ToNativePtr(config.reactiveMask); + _dispatchParams.reactiveMask = ToNativePtr(reactiveMask); _dispatchParams.outputColor = ToNativePtr(_outputIntermediate); var scaledRenderSize = config.GetScaledRenderSize(context.camera); @@ -165,6 +190,8 @@ namespace UnityEngine.Rendering.PostProcessing public uint displayHeight; public uint maxRenderWidth; public uint maxRenderHeight; + + public uint autoKeepCopies; } [Serializable, StructLayout(LayoutKind.Sequential)] @@ -172,7 +199,9 @@ namespace UnityEngine.Rendering.PostProcessing { public IntPtr color; public IntPtr depth; + public IntPtr prevDepth; public IntPtr motionVectors; + public IntPtr prevMotionVectors; public IntPtr exposure; public IntPtr reactiveMask; public IntPtr outputColor; diff --git a/Tools/PSSRPlugin/pssrplugin.cpp b/Tools/PSSRPlugin/pssrplugin.cpp index c1a958a..a9bd3dc 100644 --- a/Tools/PSSRPlugin/pssrplugin.cpp +++ b/Tools/PSSRPlugin/pssrplugin.cpp @@ -228,13 +228,17 @@ typedef struct pssr_init_params_s uint32_t displayHeight; uint32_t maxRenderWidth; uint32_t maxRenderHeight; + + uint32_t autoKeepCopies; } pssr_init_params_t; typedef struct pssr_dispatch_params_s { sce::Agc::Core::Texture* color; sce::Agc::Core::Texture* depth; + sce::Agc::Core::Texture* prevDepth; sce::Agc::Core::Texture* motionVectors; + sce::Agc::Core::Texture* prevMotionVectors; sce::Agc::Core::Texture* exposure; sce::Agc::Core::Texture* reactiveMask; sce::Agc::Core::Texture* outputColor; @@ -266,19 +270,22 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext( initParams.m_outputColorHeight = params->displayHeight; initParams.m_sharedResources = s_mfsrSharedResources; - // Keep a copy of the previous depth internally - MfsrKeepCopyTextureSpec depthCopySpec = {}; - depthCopySpec.m_width = params->maxRenderWidth; - depthCopySpec.m_height = params->maxRenderHeight; - depthCopySpec.m_bytesPerPixel = 4; // R32_SFloat - initParams.m_maxSizeDepthForKeepCopy = &depthCopySpec; - - // Keep a copy of the previous motion vectors internally - MfsrKeepCopyTextureSpec mvCopySpec = {}; - mvCopySpec.m_width = params->maxRenderWidth; - mvCopySpec.m_height = params->maxRenderHeight; - mvCopySpec.m_bytesPerPixel = 4; // R16G16_SFloat - initParams.m_maxSizeMotionVectorsForKeepCopy = &mvCopySpec; + if (params->autoKeepCopies) + { + // Keep a copy of the previous depth internally + MfsrKeepCopyTextureSpec depthCopySpec = {}; + depthCopySpec.m_width = params->maxRenderWidth; + depthCopySpec.m_height = params->maxRenderHeight; + depthCopySpec.m_bytesPerPixel = 4; // R32_SFloat + initParams.m_maxSizeDepthForKeepCopy = &depthCopySpec; + + // Keep a copy of the previous motion vectors internally + MfsrKeepCopyTextureSpec mvCopySpec = {}; + mvCopySpec.m_width = params->maxRenderWidth; + mvCopySpec.m_height = params->maxRenderHeight; + mvCopySpec.m_bytesPerPixel = 4; // R16G16_SFloat + initParams.m_maxSizeMotionVectorsForKeepCopy = &mvCopySpec; + } // Song and dance to set up memory used by this MFSR context { @@ -403,11 +410,11 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) dispatchParams.m_outputColor = params->outputColor; dispatchParams.m_color = params->color; dispatchParams.m_motionVectors = params->motionVectors; - dispatchParams.m_prevDepth = nullptr; // MFSR context keeps a copy of the previous depth internally + dispatchParams.m_prevDepth = params->prevDepth; dispatchParams.m_depth = params->depth; dispatchParams.m_exposure = params->exposure; dispatchParams.m_reactiveMask = params->reactiveMask; - dispatchParams.m_prevMotionVectors = nullptr; // MFSR context keeps a copy of the previous motion vectors internally + dispatchParams.m_prevMotionVectors = params->prevMotionVectors; dispatchParams.m_preExposure = params->preExposure; dispatchParams.m_projectionNoJitter = params->camProjectionNoJitter; dispatchParams.m_camForward = params->camForward;