diff --git a/Runtime/FrameInterpolation/FrameInterpolation.cs b/Runtime/FrameInterpolation/FrameInterpolation.cs index 900d336..9163561 100644 --- a/Runtime/FrameInterpolation/FrameInterpolation.cs +++ b/Runtime/FrameInterpolation/FrameInterpolation.cs @@ -166,14 +166,5 @@ namespace FidelityFX.FrameGen public Vector2 jitter; public Vector2 motionVectorScale; } - - [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 index 8b45296..1a436d5 100644 --- a/Runtime/FrameInterpolation/FrameInterpolationContext.cs +++ b/Runtime/FrameInterpolation/FrameInterpolationContext.cs @@ -26,7 +26,7 @@ namespace FidelityFX.FrameGen private readonly FrameInterpolationResources _resources = new FrameInterpolationResources(); private readonly ConstantsBuffer _frameInterpolationConstants = new ConstantsBuffer(); - private readonly ConstantsBuffer _spdConstants = 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"); @@ -172,7 +172,11 @@ namespace FidelityFX.FrameGen 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); + + bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) != 0; + bool infinite = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInfinite) != 0; + constants.deviceToViewDepth = FfxUtils.SetupDeviceDepthToViewSpaceDepthParams( + dispatchDescription.renderSize, dispatchDescription.cameraNear, dispatchDescription.cameraFar, dispatchDescription.cameraFovAngleVertical, inverted, infinite); _frameInterpolationConstants.UpdateBufferData(commandBuffer); @@ -196,7 +200,6 @@ namespace FidelityFX.FrameGen if (executePreparationPasses) { // Clear estimated depth resources - bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) == FrameInterpolation.InitializationFlags.EnableDepthInverted; commandBuffer.SetRenderTarget(_resources.ReconstructedDepthInterpolatedFrame); commandBuffer.ClearRenderTarget(false, true, inverted ? Color.clear : Color.white); @@ -236,66 +239,11 @@ namespace FidelityFX.FrameGen _gameVectorFieldInpaintingPyramidPass.ScheduleDispatch(commandBuffer, dispatchDescription, doubleBufferId, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); } - private Vector4 SetupDeviceDepthToViewSpaceDepthParams(FrameInterpolation.DispatchDescription dispatchParams) - { - bool inverted = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInverted) != 0; - bool infinite = (_contextDescription.flags & FrameInterpolation.InitializationFlags.EnableDepthInfinite) != 0; - - // make sure it has no impact if near and far plane values are swapped in dispatch params - // the flags "inverted" and "infinite" will decide what transform to use - float min = Mathf.Min(dispatchParams.cameraNear, dispatchParams.cameraFar); - float max = Mathf.Max(dispatchParams.cameraNear, dispatchParams.cameraFar); - - if (inverted) - { - (min, max) = (max, min); - } - - float q = max / (min - max); - float d = -1.0f; - - Vector4 matrixElemC = new Vector4(q, -1.0f - Mathf.Epsilon, q, 0.0f + Mathf.Epsilon); - Vector4 matrixElemE = new Vector4(q * min, -min - Mathf.Epsilon, q * min, max); - - // Revert x and y coords - float aspect = (float)dispatchParams.renderSize.x / dispatchParams.renderSize.y; - float cotHalfFovY = Mathf.Cos(0.5f * dispatchParams.cameraFovAngleVertical) / Mathf.Sin(0.5f * dispatchParams.cameraFovAngleVertical); - - int matrixIndex = (inverted ? 2 : 0) + (infinite ? 1 : 0); - return new Vector4( - d * matrixElemC[matrixIndex], - matrixElemE[matrixIndex], - aspect / cotHalfFovY, - 1.0f / cotHalfFovY); - } - private void SetupSpdConstants(Vector2Int resolution, out Vector2Int dispatchThreadGroupCount) { - 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.Value; - spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; - spdConstants.mips = (uint)Math.Min(numWorkGroupsAndMips.y, 7); - spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; - spdConstants.workGroupOffsetY = (uint)workGroupOffset.y; - } - - private static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1) - { - workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64); - - int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64; - int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64; - - dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y); - - numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips); - if (mips < 0) - { - float resolution = Math.Max(rectInfo.width, rectInfo.height); - numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); - } + ref var spdConstants = ref _spdConstants.Value; + FfxSpd.SetupSpdConstants(resolution, ref spdConstants, out dispatchThreadGroupCount); + spdConstants.mips = Math.Min(spdConstants.mips, 7); } private int _debugIndex = 0; diff --git a/Runtime/FrameInterpolation/FrameInterpolationPass.cs b/Runtime/FrameInterpolation/FrameInterpolationPass.cs index 7c950ea..bc6f7d8 100644 --- a/Runtime/FrameInterpolation/FrameInterpolationPass.cs +++ b/Runtime/FrameInterpolation/FrameInterpolationPass.cs @@ -288,7 +288,7 @@ namespace FidelityFX.FrameGen BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap6, Resources.InpaintingPyramid, 6); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } @@ -348,7 +348,7 @@ namespace FidelityFX.FrameGen BindMipmap(commandBuffer, FrameInterpolationShaderIDs.UavInpaintingPyramidMipmap6, Resources.InpaintingPyramid, 6); commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbFrameInterpolation, Constants, 0, Marshal.SizeOf()); - commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); + commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ); } diff --git a/Runtime/OpticalFlow/OpticalFlow.cs b/Runtime/OpticalFlow/OpticalFlow.cs index fd53982..0f5ed78 100644 --- a/Runtime/OpticalFlow/OpticalFlow.cs +++ b/Runtime/OpticalFlow/OpticalFlow.cs @@ -103,10 +103,7 @@ namespace FidelityFX.FrameGen [Serializable, StructLayout(LayoutKind.Sequential)] internal struct SpdConstants { - public uint mips; - public uint numWorkGroups; - public uint workGroupOffsetX; - public uint workGroupOffsetY; + public FfxSpd.SpdConstants spd; public uint numWorkGroupsOpticalFlowInputPyramid; public uint pad0_; diff --git a/Runtime/OpticalFlow/OpticalFlowContext.cs b/Runtime/OpticalFlow/OpticalFlowContext.cs index bec6685..78eed95 100644 --- a/Runtime/OpticalFlow/OpticalFlowContext.cs +++ b/Runtime/OpticalFlow/OpticalFlowContext.cs @@ -217,32 +217,9 @@ namespace FidelityFX.FrameGen { const int resolutionMultiplier = 1; - 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 _spdConstants.Value; - spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; - spdConstants.mips = (uint)numWorkGroupsAndMips.y; - spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; - spdConstants.workGroupOffsetY = (uint)workGroupOffset.y; - spdConstants.numWorkGroupsOpticalFlowInputPyramid = (uint)numWorkGroupsAndMips.x; - } - - private static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1) - { - workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64); - - int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64; - int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64; - - dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y); - - numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips); - if (mips < 0) - { - float resolution = Math.Max(rectInfo.width, rectInfo.height); - numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); - } + FfxSpd.SetupSpdConstants(_contextDescription.resolution * resolutionMultiplier, ref spdConstants.spd, out dispatchThreadGroupCount); + spdConstants.numWorkGroupsOpticalFlowInputPyramid = spdConstants.spd.numWorkGroups; } private static void DestroyPass(ref OpticalFlowPass pass)