Browse Source

Reworked dispatching code to use the common SPD and depth params methods.

fsr3framegen
Nico de Poel 2 years ago
parent
commit
7b988fd39d
  1. 9
      Runtime/FrameInterpolation/FrameInterpolation.cs
  2. 70
      Runtime/FrameInterpolation/FrameInterpolationContext.cs
  3. 4
      Runtime/FrameInterpolation/FrameInterpolationPass.cs
  4. 5
      Runtime/OpticalFlow/OpticalFlow.cs
  5. 27
      Runtime/OpticalFlow/OpticalFlowContext.cs

9
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;
}
}
}

70
Runtime/FrameInterpolation/FrameInterpolationContext.cs

@ -26,7 +26,7 @@ namespace FidelityFX.FrameGen
private readonly FrameInterpolationResources _resources = new FrameInterpolationResources();
private readonly ConstantsBuffer<FrameInterpolation.Constants> _frameInterpolationConstants = new ConstantsBuffer<FrameInterpolation.Constants>();
private readonly ConstantsBuffer<FrameInterpolation.InpaintingPyramidConstants> _spdConstants = new ConstantsBuffer<FrameInterpolation.InpaintingPyramidConstants>();
private readonly ConstantsBuffer<FfxSpd.SpdConstants> _spdConstants = new ConstantsBuffer<FfxSpd.SpdConstants>();
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;

4
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<FrameInterpolation.Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf<FrameInterpolation.InpaintingPyramidConstants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf<FfxSpd.SpdConstants>());
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<FrameInterpolation.Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf<FrameInterpolation.InpaintingPyramidConstants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, FrameInterpolationShaderIDs.CbInpaintingPyramid, _spdConstants, 0, Marshal.SizeOf<FfxSpd.SpdConstants>());
commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, dispatchZ);
}

5
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_;

27
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)

Loading…
Cancel
Save