Browse Source

Moved some helper methods to the static OpticalFlow class

fsr3framegen
Nico de Poel 2 years ago
parent
commit
0701d8bf52
  1. 37
      Runtime/OpticalFlow/OpticalFlow.cs
  2. 16
      Runtime/OpticalFlow/OpticalFlowContext.cs
  3. 70
      Runtime/OpticalFlow/OpticalFlowResources.cs

37
Runtime/OpticalFlow/OpticalFlow.cs

@ -6,6 +6,11 @@ namespace FidelityFX.OpticalFlow
{
public static class OpticalFlow
{
internal const int OpticalFlowMaxPyramidLevels = 7;
internal const int HistogramBins = 256;
internal const int HistogramsPerDim = 3;
internal const int HistogramShifts = 3;
public static OpticalFlowContext CreateContext(in ContextDescription contextDescription)
{
throw new NotImplementedException();
@ -27,6 +32,38 @@ namespace FidelityFX.OpticalFlow
public Vector2 minMaxLuminance;
}
internal static Vector2Int GetOpticalFlowTextureSize(Vector2Int displaySize, int opticalFlowBlockSize)
{
int width = (displaySize.x + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
int height = (displaySize.y + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
return new Vector2Int(width, height);
}
internal static Vector2Int GetOpticalFlowHistogramSize(int level)
{
const int searchRadius = 8;
int maxVelocity = searchRadius * (1 << (OpticalFlowMaxPyramidLevels - 1 - level));
int binsPerDimension = 2 * maxVelocity + 1;
return new Vector2Int(binsPerDimension, binsPerDimension);
}
internal static Vector2Int GetGlobalMotionSearchDispatchSize(int level)
{
const int threadGroupSizeX = 16;
const int threadGroupSizeY = 16;
Vector2Int opticalFlowHistogramSize = GetOpticalFlowHistogramSize(level);
int additionalElementsDueToShiftsX = opticalFlowHistogramSize.x / threadGroupSizeX;
int additionalElementsDueToShiftsY = opticalFlowHistogramSize.y / threadGroupSizeY;
int dispatchX = (opticalFlowHistogramSize.x + additionalElementsDueToShiftsX + threadGroupSizeX - 1) / threadGroupSizeX;
int dispatchY = (opticalFlowHistogramSize.y + additionalElementsDueToShiftsY + threadGroupSizeY - 1) / threadGroupSizeY;
return new Vector2Int(dispatchX, dispatchY);
}
internal static int GetSCDHistogramTextureWidth()
{
return HistogramBins * (HistogramsPerDim * HistogramsPerDim);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct OpticalFlowConstants
{

16
Runtime/OpticalFlow/OpticalFlowContext.cs

@ -32,7 +32,7 @@ namespace FidelityFX.OpticalFlow
private bool _firstExecution;
private int _resourceFrameIndex;
private readonly Vector2Int[] _opticalFlowTextureSizes = new Vector2Int[OpticalFlowResources.OpticalFlowMaxPyramidLevels];
private readonly Vector2Int[] _opticalFlowTextureSizes = new Vector2Int[OpticalFlow.OpticalFlowMaxPyramidLevels];
public void Create(OpticalFlow.ContextDescription contextDescription)
{
@ -143,23 +143,23 @@ namespace FidelityFX.OpticalFlow
{
const int threadGroupSizeX = 32;
const int threadGroupSizeY = 8;
int strataWidth = (_contextDescription.resolution.x / 4) / OpticalFlowResources.HistogramsPerDim;
int strataHeight = _contextDescription.resolution.y / OpticalFlowResources.HistogramsPerDim;
int strataWidth = (_contextDescription.resolution.x / 4) / OpticalFlow.HistogramsPerDim;
int strataHeight = _contextDescription.resolution.y / OpticalFlow.HistogramsPerDim;
int dispatchX = (strataWidth + threadGroupSizeX - 1) / threadGroupSizeX;
const int dispatchY = 16;
const int dispatchZ = OpticalFlowResources.HistogramsPerDim * OpticalFlowResources.HistogramsPerDim;
const int dispatchZ = OpticalFlow.HistogramsPerDim * OpticalFlow.HistogramsPerDim;
_generateScdHistogramPass.ScheduleDispatch(commandBuffer, dispatchDescription, frameIndex, dispatchX, dispatchY, dispatchZ);
}
{
const int dispatchX = OpticalFlowResources.HistogramsPerDim * OpticalFlowResources.HistogramsPerDim;
const int dispatchY = OpticalFlowResources.HistogramShifts;
const int dispatchX = OpticalFlow.HistogramsPerDim * OpticalFlow.HistogramsPerDim;
const int dispatchY = OpticalFlow.HistogramShifts;
_computeScdDivergencePass.ScheduleDispatch(commandBuffer, dispatchDescription, frameIndex, dispatchX, dispatchY);
}
const int pyramidMaxIterations = advancedAlgorithmIterations;
Assert.IsTrue(pyramidMaxIterations <= OpticalFlowResources.OpticalFlowMaxPyramidLevels);
Assert.IsTrue(pyramidMaxIterations <= OpticalFlow.OpticalFlowMaxPyramidLevels);
_opticalFlowTextureSizes[0] = OpticalFlowResources.GetOpticalFlowTextureSize(_contextDescription.resolution, opticalFlowBlockSize);
_opticalFlowTextureSizes[0] = OpticalFlow.GetOpticalFlowTextureSize(_contextDescription.resolution, opticalFlowBlockSize);
for (int i = 1; i < pyramidMaxIterations; ++i)
{
_opticalFlowTextureSizes[i] = new Vector2Int(

70
Runtime/OpticalFlow/OpticalFlowResources.cs

@ -5,11 +5,6 @@ namespace FidelityFX.OpticalFlow
{
internal class OpticalFlowResources
{
internal const int OpticalFlowMaxPyramidLevels = 7;
internal const int HistogramBins = 256;
internal const int HistogramsPerDim = 3;
internal const int HistogramShifts = 3;
public readonly RenderTexture[] OpticalFlowInput = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowInputLevel1 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowInputLevel2 = new RenderTexture[2];
@ -18,7 +13,7 @@ namespace FidelityFX.OpticalFlow
public readonly RenderTexture[] OpticalFlowInputLevel5 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowInputLevel6 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlow = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowLevel0 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowLevel1 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowLevel2 = new RenderTexture[2];
public readonly RenderTexture[] OpticalFlowLevel3 = new RenderTexture[2];
@ -35,7 +30,7 @@ namespace FidelityFX.OpticalFlow
Vector2Int opticalFlowInputTextureSize = contextDescription.resolution;
const int minBlockSize = 8;
Vector2Int opticalFlowTextureSize = GetOpticalFlowTextureSize(contextDescription.resolution, minBlockSize);
Vector2Int opticalFlowTextureSize = OpticalFlow.GetOpticalFlowTextureSize(contextDescription.resolution, minBlockSize);
Vector2Int opticalFlowLevel1TextureSize = NextLevelSize(opticalFlowTextureSize);
Vector2Int opticalFlowLevel2TextureSize = NextLevelSize(opticalFlowLevel1TextureSize);
Vector2Int opticalFlowLevel3TextureSize = NextLevelSize(opticalFlowLevel2TextureSize);
@ -43,8 +38,8 @@ namespace FidelityFX.OpticalFlow
Vector2Int opticalFlowLevel5TextureSize = NextLevelSize(opticalFlowLevel4TextureSize);
Vector2Int opticalFlowLevel6TextureSize = NextLevelSize(opticalFlowLevel5TextureSize);
Vector2Int opticalFlowHistogramTextureSize = GetOpticalFlowHistogramSize(0);
Vector2Int globalMotionSearchMaxDispatchSize = GetGlobalMotionSearchDispatchSize(0);
Vector2Int opticalFlowHistogramTextureSize = OpticalFlow.GetOpticalFlowHistogramSize(0);
Vector2Int globalMotionSearchMaxDispatchSize = OpticalFlow.GetGlobalMotionSearchDispatchSize(0);
int globalMotionSearchTextureWidth = 4 + (globalMotionSearchMaxDispatchSize.x * globalMotionSearchMaxDispatchSize.y);
CreateDoubleBufferedResource(OpticalFlowInput, "OPTICALFLOW_OpticalFlowInput", opticalFlowInputTextureSize, GraphicsFormat.R8_UInt);
@ -61,7 +56,7 @@ namespace FidelityFX.OpticalFlow
opticalFlowInputTextureSize = new Vector2Int(opticalFlowInputTextureSize.x >> 1, opticalFlowInputTextureSize.y >> 1);
CreateDoubleBufferedResource(OpticalFlowInputLevel6, "OPTICALFLOW_OpticalFlowInputLevel6-", opticalFlowInputTextureSize, GraphicsFormat.R8_UInt);
CreateDoubleBufferedResource(OpticalFlow, "OPTICALFLOW_OpticalFlow", opticalFlowTextureSize, GraphicsFormat.R16G16_SInt);
CreateDoubleBufferedResource(OpticalFlowLevel0, "OPTICALFLOW_OpticalFlow", opticalFlowTextureSize, GraphicsFormat.R16G16_SInt);
CreateDoubleBufferedResource(OpticalFlowLevel1, "OPTICALFLOW_OpticalFlowLevel1-", opticalFlowLevel1TextureSize, GraphicsFormat.R16G16_SInt);
CreateDoubleBufferedResource(OpticalFlowLevel2, "OPTICALFLOW_OpticalFlowLevel2-", opticalFlowLevel2TextureSize, GraphicsFormat.R16G16_SInt);
CreateDoubleBufferedResource(OpticalFlowLevel3, "OPTICALFLOW_OpticalFlowLevel3-", opticalFlowLevel3TextureSize, GraphicsFormat.R16G16_SInt);
@ -69,8 +64,8 @@ namespace FidelityFX.OpticalFlow
CreateDoubleBufferedResource(OpticalFlowLevel5, "OPTICALFLOW_OpticalFlowLevel5-", opticalFlowLevel5TextureSize, GraphicsFormat.R16G16_SInt);
CreateDoubleBufferedResource(OpticalFlowLevel6, "OPTICALFLOW_OpticalFlowLevel6-", opticalFlowLevel6TextureSize, GraphicsFormat.R16G16_SInt);
OpticalFlowSCDHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDHistogram", new Vector2Int(GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_UInt);
OpticalFlowSCDPreviousHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDPreviousHistogram", new Vector2Int(GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_SFloat);
OpticalFlowSCDHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDHistogram", new Vector2Int(OpticalFlow.GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_UInt);
OpticalFlowSCDPreviousHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDPreviousHistogram", new Vector2Int(OpticalFlow.GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_SFloat);
OpticalFlowSCDTemp = CreateResource("OPTICALFLOW_OpticalFlowSCDTemp", new Vector2Int(3, 1), GraphicsFormat.R32_UInt);
}
@ -86,7 +81,7 @@ namespace FidelityFX.OpticalFlow
DestroyResource(OpticalFlowLevel3);
DestroyResource(OpticalFlowLevel2);
DestroyResource(OpticalFlowLevel1);
DestroyResource(OpticalFlow);
DestroyResource(OpticalFlowLevel0);
DestroyResource(OpticalFlowInputLevel6);
DestroyResource(OpticalFlowInputLevel5);
@ -107,39 +102,6 @@ namespace FidelityFX.OpticalFlow
return (x + (y - 1)) & ~(y - 1);
}
// TODO: move these to OpticalFlow class
internal static Vector2Int GetOpticalFlowTextureSize(Vector2Int displaySize, int opticalFlowBlockSize)
{
int width = (displaySize.x + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
int height = (displaySize.y + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
return new Vector2Int(width, height);
}
private static Vector2Int GetOpticalFlowHistogramSize(int level)
{
const int searchRadius = 8;
int maxVelocity = searchRadius * (1 << (OpticalFlowMaxPyramidLevels - 1 - level));
int binsPerDimension = 2 * maxVelocity + 1;
return new Vector2Int(binsPerDimension, binsPerDimension);
}
private static Vector2Int GetGlobalMotionSearchDispatchSize(int level)
{
const int threadGroupSizeX = 16;
const int threadGroupSizeY = 16;
Vector2Int opticalFlowHistogramSize = GetOpticalFlowHistogramSize(level);
int additionalElementsDueToShiftsX = opticalFlowHistogramSize.x / threadGroupSizeX;
int additionalElementsDueToShiftsY = opticalFlowHistogramSize.y / threadGroupSizeY;
int dispatchX = (opticalFlowHistogramSize.x + additionalElementsDueToShiftsX + threadGroupSizeX - 1) / threadGroupSizeX;
int dispatchY = (opticalFlowHistogramSize.y + additionalElementsDueToShiftsY + threadGroupSizeY - 1) / threadGroupSizeY;
return new Vector2Int(dispatchX, dispatchY);
}
private static int GetSCDHistogramTextureWidth()
{
return HistogramBins * (HistogramsPerDim * HistogramsPerDim);
}
private static RenderTexture CreateResource(string name, Vector2Int size, GraphicsFormat format)
{
var rt = new RenderTexture(size.x, size.y, 0, format) { name = name, enableRandomWrite = true };
@ -155,22 +117,6 @@ namespace FidelityFX.OpticalFlow
resource[i].Create();
}
}
private static void DestroyResource(ref Texture2D resource)
{
if (resource == null)
return;
#if UNITY_EDITOR
if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused)
UnityEngine.Object.Destroy(resource);
else
UnityEngine.Object.DestroyImmediate(resource);
#else
UnityEngine.Object.Destroy(resource);
#endif
resource = null;
}
private static void DestroyResource(ref RenderTexture resource)
{

Loading…
Cancel
Save