diff --git a/Runtime/FrameInterpolation/FrameInterpolation.cs b/Runtime/FrameInterpolation/FrameInterpolation.cs new file mode 100644 index 0000000..7839029 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolation.cs @@ -0,0 +1,53 @@ +using System; +using System.Runtime.InteropServices; + +namespace FidelityFX.FrameGen +{ + public static class FrameInterpolation + { + public struct ContextDescription + { + + } + + // TODO: turn all of these into structs + public class DispatchDescription + { + + } + + [Flags] + public enum InitializationFlags + { + EnableDepthInverted = 1 << 0, + EnableDepthInfinite = 1 << 1, + EnableHDRColorInput = 1 << 3, + EnableDisplayResolutionMotionVectors = 1 << 4, + EnableJitterMotionVectors = 1 << 5, + EnableAsyncSupport = 1 << 6, + } + + [Flags] + public enum DispatchFlags + { + DrawDebugTearLines = 1 << 0, + DrawDebugResetIndicators = 1 << 1, + DrawDebugView = 1 << 2, + } + + [Serializable, StructLayout(LayoutKind.Sequential)] + internal struct Constants + { + + } + + [Serializable, StructLayout(LayoutKind.Sequential)] + internal struct InpaintingPyramidConstants + { + public uint mips; + public uint numWorkGroups; + public uint workGroupOffsetX; + public uint workGroupOffsetY; + } + } +} diff --git a/Runtime/FrameInterpolation/FrameInterpolationContext.cs b/Runtime/FrameInterpolation/FrameInterpolationContext.cs new file mode 100644 index 0000000..6c7d432 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationContext.cs @@ -0,0 +1,101 @@ +using System.Runtime.InteropServices; +using UnityEngine; +using UnityEngine.Profiling; +using UnityEngine.Rendering; + +namespace FidelityFX.FrameGen +{ + public class FrameInterpolationContext + { + private FrameInterpolation.ContextDescription _contextDescription; + + private FrameInterpolationPass _reconstructAndDilatePass; + private FrameInterpolationPass _setupPass; + private FrameInterpolationPass _reconstructPreviousDepthPass; + private FrameInterpolationPass _gameMotionVectorFieldPass; + private FrameInterpolationPass _opticalFlowVectorFieldPass; + private FrameInterpolationPass _disocclusionMaskPass; + private FrameInterpolationPass _scfiPass; + private FrameInterpolationPass _inpaintingPyramidPass; + private FrameInterpolationPass _inpaintingPass; + private FrameInterpolationPass _gameVectorFieldInpaintingPyramidPass; + 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 CustomSampler _sampler = CustomSampler.Create("Frame Interpolation"); + + public void Create(in FrameInterpolation.ContextDescription contextDescription) + { + _contextDescription = contextDescription; + + _frameInterpolationConstantsBuffer = CreateConstantBuffer(); + _spdConstantsBuffer = CreateConstantBuffer(); + + CreatePasses(); + } + + private void CreatePasses() + { + + } + + public void Destroy() + { + DestroyPass(ref _debugViewPass); + DestroyPass(ref _gameVectorFieldInpaintingPyramidPass); + DestroyPass(ref _inpaintingPass); + DestroyPass(ref _inpaintingPyramidPass); + DestroyPass(ref _scfiPass); + DestroyPass(ref _disocclusionMaskPass); + DestroyPass(ref _opticalFlowVectorFieldPass); + DestroyPass(ref _gameMotionVectorFieldPass); + DestroyPass(ref _reconstructPreviousDepthPass); + DestroyPass(ref _setupPass); + DestroyPass(ref _reconstructAndDilatePass); + + _resources.Destroy(); + + DestroyConstantBuffer(ref _spdConstantsBuffer); + DestroyConstantBuffer(ref _frameInterpolationConstantsBuffer); + } + + public void Dispatch(CommandBuffer commandBuffer, FrameInterpolation.DispatchDescription dispatchDescription) + { + commandBuffer.BeginSample(_sampler); + + commandBuffer.EndSample(_sampler); + } + + 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) + { + if (pass == null) + return; + + pass.Dispose(); + pass = null; + } + } +} diff --git a/Runtime/FrameInterpolation/FrameInterpolationPass.cs b/Runtime/FrameInterpolation/FrameInterpolationPass.cs new file mode 100644 index 0000000..b2d8269 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationPass.cs @@ -0,0 +1,53 @@ +using System; +using UnityEngine; +using UnityEngine.Profiling; +using UnityEngine.Rendering; + +namespace FidelityFX.FrameGen +{ + internal abstract class FrameInterpolationPass: IDisposable + { + protected readonly FrameInterpolation.ContextDescription ContextDescription; + protected readonly FrameInterpolationResources Resources; + protected readonly ComputeBuffer Constants; + + protected ComputeShader ComputeShader; + protected int KernelIndex; + + private CustomSampler _sampler; + + protected FrameInterpolationPass(FrameInterpolation.ContextDescription contextDescription, FrameInterpolationResources resources, ComputeBuffer constants) + { + ContextDescription = contextDescription; + Resources = resources; + Constants = constants; + } + + public virtual void Dispose() + { + } + + public void ScheduleDispatch(CommandBuffer commandBuffer, OpticalFlow.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ = 1) + { + commandBuffer.BeginSample(_sampler); + DoScheduleDispatch(commandBuffer, dispatchParams, frameIndex, dispatchX, dispatchY, dispatchZ); + commandBuffer.EndSample(_sampler); + } + + protected abstract void DoScheduleDispatch(CommandBuffer commandBuffer, OpticalFlow.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY, int dispatchZ); + + protected void InitComputeShader(string passName, ComputeShader shader) + { + if (shader == null) + { + throw new MissingReferenceException($"Shader for Frame Interpolation pass '{passName}' could not be loaded! Please ensure it is included in the project correctly."); + } + + ComputeShader = shader; + KernelIndex = ComputeShader.FindKernel("CS"); + _sampler = CustomSampler.Create(passName); + + // TODO: shader variants + } + } +} diff --git a/Runtime/FrameInterpolation/FrameInterpolationResources.cs b/Runtime/FrameInterpolation/FrameInterpolationResources.cs new file mode 100644 index 0000000..0b2186f --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationResources.cs @@ -0,0 +1,10 @@ +namespace FidelityFX.FrameGen +{ + internal class FrameInterpolationResources + { + public void Destroy() + { + + } + } +} diff --git a/Runtime/FrameInterpolation/FrameInterpolationShaderIDs.cs b/Runtime/FrameInterpolation/FrameInterpolationShaderIDs.cs new file mode 100644 index 0000000..60eaf67 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationShaderIDs.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +namespace FidelityFX.FrameGen +{ + public static class FrameInterpolationShaderIDs + { + public static readonly int SrvInputDepth = Shader.PropertyToID("r_input_depth"); + public static readonly int SrvInputMotionVectors = Shader.PropertyToID("r_input_motion_vectors"); + } +}