diff --git a/Runtime/FrameInterpolation/FrameInterpolationContext.cs b/Runtime/FrameInterpolation/FrameInterpolationContext.cs index 789b36e..8b45296 100644 --- a/Runtime/FrameInterpolation/FrameInterpolationContext.cs +++ b/Runtime/FrameInterpolation/FrameInterpolationContext.cs @@ -7,7 +7,7 @@ using UnityEngine.Rendering; namespace FidelityFX.FrameGen { - public class FrameInterpolationContext + public class FrameInterpolationContext: FfxContextBase { private FrameInterpolation.ContextDescription _contextDescription; @@ -24,14 +24,9 @@ namespace FidelityFX.FrameGen private FrameInterpolationPass _debugViewPass; private readonly FrameInterpolationResources _resources = new FrameInterpolationResources(); - - private ComputeBuffer _frameInterpolationConstantsBuffer; - private readonly FrameInterpolation.Constants[] _frameInterpolationConstantsArray = { new FrameInterpolation.Constants() }; - private ref FrameInterpolation.Constants Constants => ref _frameInterpolationConstantsArray[0]; - - private ComputeBuffer _spdConstantsBuffer; - private readonly FrameInterpolation.InpaintingPyramidConstants[] _spdConstantsArray = { new FrameInterpolation.InpaintingPyramidConstants() }; - private ref FrameInterpolation.InpaintingPyramidConstants SpdConstants => ref _spdConstantsArray[0]; + + private readonly ConstantsBuffer _frameInterpolationConstants = new ConstantsBuffer(); + private readonly ConstantsBuffer _spdConstants = new ConstantsBuffer(); private readonly CustomSampler _sampler = CustomSampler.Create("Frame Interpolation"); private readonly CustomSampler _prepareSampler = CustomSampler.Create("Frame Interpolation - Prepare"); @@ -44,19 +39,20 @@ namespace FidelityFX.FrameGen { _contextDescription = contextDescription; - _frameInterpolationConstantsBuffer = CreateConstantBuffer(); - _spdConstantsBuffer = CreateConstantBuffer(); + _frameInterpolationConstants.Create(); + _spdConstants.Create(); _firstExecution = true; _previousFrameID = 0; _asyncSupported = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableAsyncSupport) == FrameInterpolation.InitializationFlags.EnableAsyncSupport; - Constants.maxRenderSize = _contextDescription.maxRenderSize; - Constants.displaySize = _contextDescription.displaySize; - Constants.displaySizeRcp.x = 1.0f / _contextDescription.displaySize.x; - Constants.displaySizeRcp.y = 1.0f / _contextDescription.displaySize.y; - Constants.interpolationRectBase = Vector2Int.zero; - Constants.interpolationRectSize = _contextDescription.displaySize; + ref var constants = ref _frameInterpolationConstants.Value; + constants.maxRenderSize = _contextDescription.maxRenderSize; + constants.displaySize = _contextDescription.displaySize; + constants.displaySizeRcp.x = 1.0f / _contextDescription.displaySize.x; + constants.displaySizeRcp.y = 1.0f / _contextDescription.displaySize.y; + constants.interpolationRectBase = Vector2Int.zero; + constants.interpolationRectSize = _contextDescription.displaySize; _resources.Create(_contextDescription); CreatePasses(); @@ -64,17 +60,17 @@ namespace FidelityFX.FrameGen private void CreatePasses() { - _reconstructAndDilatePass = new FrameInterpolationReconstructAndDilatePass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _setupPass = new FrameInterpolationSetupPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _reconstructPreviousDepthPass = new FrameInterpolationReconstructPreviousDepthPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _gameMotionVectorFieldPass = new FrameInterpolationGameMotionVectorFieldPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _opticalFlowVectorFieldPass = new FrameInterpolationOpticalFlowVectorFieldPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _disocclusionMaskPass = new FrameInterpolationDisocclusionMaskPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _interpolationPass = new FrameInterpolationInterpolationPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _inpaintingPyramidPass = new FrameInterpolationInpaintingPyramidPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer, _spdConstantsBuffer); - _inpaintingPass = new FrameInterpolationInpaintingPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); - _gameVectorFieldInpaintingPyramidPass = new FrameInterpolationGameVectorFieldInpaintingPyramidPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer, _spdConstantsBuffer); - _debugViewPass = new FrameInterpolationDebugViewPass(_contextDescription, _resources, _frameInterpolationConstantsBuffer); + _reconstructAndDilatePass = new FrameInterpolationReconstructAndDilatePass(_contextDescription, _resources, _frameInterpolationConstants); + _setupPass = new FrameInterpolationSetupPass(_contextDescription, _resources, _frameInterpolationConstants); + _reconstructPreviousDepthPass = new FrameInterpolationReconstructPreviousDepthPass(_contextDescription, _resources, _frameInterpolationConstants); + _gameMotionVectorFieldPass = new FrameInterpolationGameMotionVectorFieldPass(_contextDescription, _resources, _frameInterpolationConstants); + _opticalFlowVectorFieldPass = new FrameInterpolationOpticalFlowVectorFieldPass(_contextDescription, _resources, _frameInterpolationConstants); + _disocclusionMaskPass = new FrameInterpolationDisocclusionMaskPass(_contextDescription, _resources, _frameInterpolationConstants); + _interpolationPass = new FrameInterpolationInterpolationPass(_contextDescription, _resources, _frameInterpolationConstants); + _inpaintingPyramidPass = new FrameInterpolationInpaintingPyramidPass(_contextDescription, _resources, _frameInterpolationConstants, _spdConstants); + _inpaintingPass = new FrameInterpolationInpaintingPass(_contextDescription, _resources, _frameInterpolationConstants); + _gameVectorFieldInpaintingPyramidPass = new FrameInterpolationGameVectorFieldInpaintingPyramidPass(_contextDescription, _resources, _frameInterpolationConstants, _spdConstants); + _debugViewPass = new FrameInterpolationDebugViewPass(_contextDescription, _resources, _frameInterpolationConstants); } public void Destroy() @@ -93,8 +89,8 @@ namespace FidelityFX.FrameGen _resources.Destroy(); - DestroyConstantBuffer(ref _spdConstantsBuffer); - DestroyConstantBuffer(ref _frameInterpolationConstantsBuffer); + _spdConstants.Destroy(); + _frameInterpolationConstants.Destroy(); } public void Prepare(CommandBuffer commandBuffer, FrameInterpolation.PrepareDescription prepareDescription) @@ -103,13 +99,14 @@ namespace FidelityFX.FrameGen int doubleBufferId = _asyncSupported ? (int)(prepareDescription.frameID & 1) : 0; - Constants.renderSize = prepareDescription.renderSize; - Constants.jitter = prepareDescription.jitterOffset; - Vector2Int motionVectorsTargetSize = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDisplayResolutionMotionVectors) != 0 ? Constants.displaySize : Constants.renderSize; - Constants.motionVectorScale.x = prepareDescription.motionVectorScale.x / motionVectorsTargetSize.x; - Constants.motionVectorScale.y = prepareDescription.motionVectorScale.y / motionVectorsTargetSize.y; + ref var constants = ref _frameInterpolationConstants.Value; + constants.renderSize = prepareDescription.renderSize; + constants.jitter = prepareDescription.jitterOffset; + Vector2Int motionVectorsTargetSize = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDisplayResolutionMotionVectors) != 0 ? constants.displaySize : constants.renderSize; + constants.motionVectorScale.x = prepareDescription.motionVectorScale.x / motionVectorsTargetSize.x; + constants.motionVectorScale.y = prepareDescription.motionVectorScale.y / motionVectorsTargetSize.y; - commandBuffer.SetBufferData(_frameInterpolationConstantsBuffer, _frameInterpolationConstantsArray); + _frameInterpolationConstants.UpdateBufferData(commandBuffer); Assert.IsTrue(prepareDescription.depth.IsValid); Assert.IsTrue(prepareDescription.motionVectors.IsValid); @@ -142,41 +139,42 @@ namespace FidelityFX.FrameGen bool disjointFrameId = frameIdDecreased || frameIdSkipped; _previousFrameID = dispatchDescription.frameID; - Constants.renderSize = dispatchDescription.renderSize; - Constants.displaySize = dispatchDescription.displaySize; - Constants.displaySizeRcp.x = 1.0f / dispatchDescription.displaySize.x; - Constants.displaySizeRcp.y = 1.0f / dispatchDescription.displaySize.y; - Constants.upscalerTargetSize = dispatchDescription.interpolationRect.size; - Constants.mode = 0; - Constants.reset = (reset || disjointFrameId) ? 1 : 0; - Constants.deltaTime = dispatchDescription.frameTimeDelta; - Constants.HUDLessAttachedFactor = dispatchDescription.currentBackBuffer_HUDLess.IsValid ? 1 : 0; + ref var constants = ref _frameInterpolationConstants.Value; + constants.renderSize = dispatchDescription.renderSize; + constants.displaySize = dispatchDescription.displaySize; + constants.displaySizeRcp.x = 1.0f / dispatchDescription.displaySize.x; + constants.displaySizeRcp.y = 1.0f / dispatchDescription.displaySize.y; + constants.upscalerTargetSize = dispatchDescription.interpolationRect.size; + constants.mode = 0; + constants.reset = (reset || disjointFrameId) ? 1 : 0; + constants.deltaTime = dispatchDescription.frameTimeDelta; + constants.HUDLessAttachedFactor = dispatchDescription.currentBackBuffer_HUDLess.IsValid ? 1 : 0; - Constants.opticalFlowScale = dispatchDescription.opticalFlowScale; - Constants.opticalFlowBlockSize = dispatchDescription.opticalFlowBlockSize; - Constants.dispatchFlags = (uint)dispatchDescription.flags; + constants.opticalFlowScale = dispatchDescription.opticalFlowScale; + constants.opticalFlowBlockSize = dispatchDescription.opticalFlowBlockSize; + constants.dispatchFlags = (uint)dispatchDescription.flags; - Constants.cameraNear = dispatchDescription.cameraNear; - Constants.cameraFar = dispatchDescription.cameraFar; + constants.cameraNear = dispatchDescription.cameraNear; + constants.cameraFar = dispatchDescription.cameraFar; - Constants.interpolationRectBase = dispatchDescription.interpolationRect.position; - Constants.interpolationRectSize = dispatchDescription.interpolationRect.size; + constants.interpolationRectBase = dispatchDescription.interpolationRect.position; + constants.interpolationRectSize = dispatchDescription.interpolationRect.size; // Debug bar - Constants.debugBarColor.x = DebugBarColorSequence[_debugIndex * 3 + 0]; - Constants.debugBarColor.y = DebugBarColorSequence[_debugIndex * 3 + 1]; - Constants.debugBarColor.z = DebugBarColorSequence[_debugIndex * 3 + 2]; + constants.debugBarColor.x = DebugBarColorSequence[_debugIndex * 3 + 0]; + constants.debugBarColor.y = DebugBarColorSequence[_debugIndex * 3 + 1]; + constants.debugBarColor.z = DebugBarColorSequence[_debugIndex * 3 + 2]; _debugIndex = (_debugIndex + 1) % (DebugBarColorSequence.Length / 3); - Constants.backBufferTransferFunction = (uint)dispatchDescription.backbufferTransferFunction; - Constants.minMaxLuminance = dispatchDescription.minMaxLuminance; + constants.backBufferTransferFunction = (uint)dispatchDescription.backbufferTransferFunction; + constants.minMaxLuminance = dispatchDescription.minMaxLuminance; float aspectRatio = dispatchDescription.renderSize.x / (float)dispatchDescription.renderSize.y; float cameraAngleHorizontal = Mathf.Atan(Mathf.Tan(dispatchDescription.cameraFovAngleVertical / 2) * aspectRatio) * 2; - Constants.tanHalfFOV = Mathf.Tan(cameraAngleHorizontal * 0.5f); - Constants.deviceToViewDepth = SetupDeviceDepthToViewSpaceDepthParams(dispatchDescription); + constants.tanHalfFOV = Mathf.Tan(cameraAngleHorizontal * 0.5f); + constants.deviceToViewDepth = SetupDeviceDepthToViewSpaceDepthParams(dispatchDescription); - commandBuffer.SetBufferData(_frameInterpolationConstantsBuffer, _frameInterpolationConstantsArray); + _frameInterpolationConstants.UpdateBufferData(commandBuffer); int doubleBufferId = _asyncSupported ? (int)(dispatchDescription.frameID & 1) : 0; @@ -189,7 +187,7 @@ namespace FidelityFX.FrameGen int opticalFlowDispatchSizeX = (int)(dispatchDescription.displaySize.x / (float)dispatchDescription.opticalFlowBlockSize + 7) / 8; int opticalFlowDispatchSizeY = (int)(dispatchDescription.displaySize.y / (float)dispatchDescription.opticalFlowBlockSize + 7) / 8; - bool executePreparationPasses = (Constants.reset == 0); + bool executePreparationPasses = (constants.reset == 0); // Schedule work for the interpolation command list _setupPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, renderDispatchSizeX, renderDispatchSizeY); @@ -213,7 +211,7 @@ namespace FidelityFX.FrameGen // Inpainting pyramid SetupSpdConstants(dispatchDescription.displaySize, out var dispatchThreadGroupCount); - commandBuffer.SetBufferData(_spdConstantsBuffer, _spdConstantsArray); + _spdConstants.UpdateBufferData(commandBuffer); _inpaintingPyramidPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); _inpaintingPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, displayDispatchSizeX, displayDispatchSizeY); @@ -234,7 +232,7 @@ namespace FidelityFX.FrameGen private void DispatchGameVectorFieldInpaintingPyramid(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchDescription, int doubleBufferId) { SetupSpdConstants(dispatchDescription.renderSize, out var dispatchThreadGroupCount); - commandBuffer.SetBufferData(_spdConstantsBuffer, _spdConstantsArray); + _spdConstants.UpdateBufferData(commandBuffer); _gameVectorFieldInpaintingPyramidPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); } @@ -276,7 +274,7 @@ namespace FidelityFX.FrameGen RectInt rectInfo = new RectInt(0, 0, resolution.x, resolution.y); SpdSetup(rectInfo, out dispatchThreadGroupCount, out var workGroupOffset, out var numWorkGroupsAndMips); - ref FrameInterpolation.InpaintingPyramidConstants spdConstants = ref SpdConstants; + ref FrameInterpolation.InpaintingPyramidConstants spdConstants = ref _spdConstants.Value; spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; spdConstants.mips = (uint)Math.Min(numWorkGroupsAndMips.y, 7); spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; @@ -311,20 +309,6 @@ namespace FidelityFX.FrameGen 0.0f, 1.0f, 0.1f, // green 1.0f, 1.0f, 0.48f // bright yellow }; - - private static ComputeBuffer CreateConstantBuffer() where TConstants: struct - { - return new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); - } - - private static void DestroyConstantBuffer(ref ComputeBuffer bufferRef) - { - if (bufferRef == null) - return; - - bufferRef.Release(); - bufferRef = null; - } private static void DestroyPass(ref FrameInterpolationPass pass) { diff --git a/Runtime/OpticalFlow/OpticalFlowContext.cs b/Runtime/OpticalFlow/OpticalFlowContext.cs index 739a4d8..bec6685 100644 --- a/Runtime/OpticalFlow/OpticalFlowContext.cs +++ b/Runtime/OpticalFlow/OpticalFlowContext.cs @@ -7,7 +7,7 @@ using UnityEngine.Rendering; namespace FidelityFX.FrameGen { - public class OpticalFlowContext + public class OpticalFlowContext: FfxContextBase { private const int MaxQueuedFrames = 16; @@ -22,14 +22,9 @@ namespace FidelityFX.FrameGen private OpticalFlowPass _scaleOpticalFlowPass; private readonly OpticalFlowResources _resources = new OpticalFlowResources(); - - private ComputeBuffer _opticalFlowConstantsBuffer; - private readonly OpticalFlow.OpticalFlowConstants[] _opticalFlowConstantsArray = { new OpticalFlow.OpticalFlowConstants() }; - private ref OpticalFlow.OpticalFlowConstants Constants => ref _opticalFlowConstantsArray[0]; - - private ComputeBuffer _spdConstantsBuffer; - private readonly OpticalFlow.SpdConstants[] _spdConstantsArray = { new OpticalFlow.SpdConstants() }; - private ref OpticalFlow.SpdConstants SpdConsts => ref _spdConstantsArray[0]; + + private readonly ConstantsBuffer _opticalFlowConstants = new ConstantsBuffer(); + private readonly ConstantsBuffer _spdConstants = new ConstantsBuffer(); private bool _firstExecution; private int _resourceFrameIndex; @@ -40,13 +35,13 @@ namespace FidelityFX.FrameGen { _contextDescription = contextDescription; - _opticalFlowConstantsBuffer = CreateConstantBuffer(); - _spdConstantsBuffer = CreateConstantBuffer(); + _opticalFlowConstants.Create(); + _spdConstants.Create(); _firstExecution = true; _resourceFrameIndex = 0; - Constants.inputLumaResolution = _contextDescription.resolution; + _opticalFlowConstants.Value.inputLumaResolution = _contextDescription.resolution; _resources.Create(_contextDescription); CreatePasses(); @@ -54,13 +49,13 @@ namespace FidelityFX.FrameGen private void CreatePasses() { - _prepareLumaPass = new OpticalFlowPrepareLumaPass(_contextDescription, _resources, _opticalFlowConstantsBuffer); - _generateInputPyramidPass = new OpticalFlowGenerateInputPyramidPass(_contextDescription, _resources, _opticalFlowConstantsBuffer, _spdConstantsBuffer); - _generateScdHistogramPass = new OpticalFlowGenerateSCDHistogramPass(_contextDescription, _resources, _opticalFlowConstantsBuffer); - _computeScdDivergencePass = new OpticalFlowComputeSCDDivergencePass(_contextDescription, _resources, _opticalFlowConstantsBuffer); - _computeOpticalFlowPass = new OpticalFlowComputePass(_contextDescription, _resources, _opticalFlowConstantsBuffer); - _filterOpticalFlowPass = new OpticalFlowFilterPass(_contextDescription, _resources, _opticalFlowConstantsBuffer); - _scaleOpticalFlowPass = new OpticalFlowScalePass(_contextDescription, _resources, _opticalFlowConstantsBuffer); + _prepareLumaPass = new OpticalFlowPrepareLumaPass(_contextDescription, _resources, _opticalFlowConstants); + _generateInputPyramidPass = new OpticalFlowGenerateInputPyramidPass(_contextDescription, _resources, _opticalFlowConstants, _spdConstants); + _generateScdHistogramPass = new OpticalFlowGenerateSCDHistogramPass(_contextDescription, _resources, _opticalFlowConstants); + _computeScdDivergencePass = new OpticalFlowComputeSCDDivergencePass(_contextDescription, _resources, _opticalFlowConstants); + _computeOpticalFlowPass = new OpticalFlowComputePass(_contextDescription, _resources, _opticalFlowConstants); + _filterOpticalFlowPass = new OpticalFlowFilterPass(_contextDescription, _resources, _opticalFlowConstants); + _scaleOpticalFlowPass = new OpticalFlowScalePass(_contextDescription, _resources, _opticalFlowConstants); } public void Destroy() @@ -75,8 +70,8 @@ namespace FidelityFX.FrameGen _resources.Destroy(); - DestroyConstantBuffer(ref _spdConstantsBuffer); - DestroyConstantBuffer(ref _opticalFlowConstantsBuffer); + _spdConstants.Destroy(); + _opticalFlowConstants.Destroy(); } public void Dispatch(CommandBuffer commandBuffer, OpticalFlow.DispatchDescription dispatchDescription) @@ -84,17 +79,18 @@ namespace FidelityFX.FrameGen const int advancedAlgorithmIterations = 7; const int opticalFlowBlockSize = 8; - Constants.backbufferTransferFunction = (uint)dispatchDescription.BackbufferTransferFunction; - Constants.minMaxLuminance = dispatchDescription.MinMaxLuminance; + ref var constants = ref _opticalFlowConstants.Value; + constants.backbufferTransferFunction = (uint)dispatchDescription.BackbufferTransferFunction; + constants.minMaxLuminance = dispatchDescription.MinMaxLuminance; int frameIndex = _resourceFrameIndex % 2; bool resetAccumulation = dispatchDescription.Reset || _firstExecution; _firstExecution = false; if (resetAccumulation) - Constants.frameIndex = 0; + constants.frameIndex = 0; else - Constants.frameIndex++; + constants.frameIndex++; commandBuffer.BeginSample(_sampler); @@ -120,8 +116,8 @@ namespace FidelityFX.FrameGen SetupSpdConstants(out var threadGroupSizeOpticalFlowInputPyramid); - commandBuffer.SetBufferData(_opticalFlowConstantsBuffer, _opticalFlowConstantsArray); - commandBuffer.SetBufferData(_spdConstantsBuffer, _spdConstantsArray); + _opticalFlowConstants.UpdateBufferData(commandBuffer); + _spdConstants.UpdateBufferData(commandBuffer); { const int threadGroupSizeX = 16; @@ -165,9 +161,9 @@ namespace FidelityFX.FrameGen for (int level = pyramidMaxIterations - 1; level >= 0; --level) { - Constants.opticalFlowPyramidLevel = (uint)level; - Constants.opticalFlowPyramidLevelCount = pyramidMaxIterations; - commandBuffer.SetBufferData(_opticalFlowConstantsBuffer, _opticalFlowConstantsArray); + constants.opticalFlowPyramidLevel = (uint)level; + constants.opticalFlowPyramidLevelCount = pyramidMaxIterations; + _opticalFlowConstants.UpdateBufferData(commandBuffer); { int inputLumaWidth = Math.Max(_contextDescription.resolution.x >> level, 1); @@ -224,7 +220,7 @@ namespace FidelityFX.FrameGen RectInt rectInfo = new RectInt(0, 0, _contextDescription.resolution.x * resolutionMultiplier, _contextDescription.resolution.y * resolutionMultiplier); SpdSetup(rectInfo, out dispatchThreadGroupCount, out var workGroupOffset, out var numWorkGroupsAndMips, 4); - ref OpticalFlow.SpdConstants spdConstants = ref SpdConsts; + ref OpticalFlow.SpdConstants spdConstants = ref _spdConstants.Value; spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; spdConstants.mips = (uint)numWorkGroupsAndMips.y; spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; @@ -248,20 +244,6 @@ namespace FidelityFX.FrameGen numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); } } - - private static ComputeBuffer CreateConstantBuffer() where TConstants: struct - { - return new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); - } - - private static void DestroyConstantBuffer(ref ComputeBuffer bufferRef) - { - if (bufferRef == null) - return; - - bufferRef.Release(); - bufferRef = null; - } private static void DestroyPass(ref OpticalFlowPass pass) {