You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

112 lines
4.7 KiB

using UnityEngine;
using UnityEngine.Experimental.Rendering;
namespace FidelityFX.FrameGen
{
internal class OpticalFlowResources
{
public readonly RenderTexture[][] OpticalFlowInputLevels =
{
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
};
public readonly RenderTexture[][] OpticalFlowLevels =
{
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
new RenderTexture[2],
};
public RenderTexture OpticalFlowSCDHistogram;
public RenderTexture OpticalFlowSCDPreviousHistogram;
public RenderTexture OpticalFlowSCDTemp;
public void Create(OpticalFlow.ContextDescription contextDescription)
{
Vector2Int opticalFlowInputTextureSize = contextDescription.resolution;
Vector2Int opticalFlowTextureSize = OpticalFlow.GetOpticalFlowTextureSize(contextDescription.resolution, OpticalFlow.MinBlockSize);
// TODO: this seems useless, delete unless something comes up
Vector2Int opticalFlowHistogramTextureSize = OpticalFlow.GetOpticalFlowHistogramSize(0);
Vector2Int globalMotionSearchMaxDispatchSize = OpticalFlow.GetGlobalMotionSearchDispatchSize(0);
int globalMotionSearchTextureWidth = 4 + (globalMotionSearchMaxDispatchSize.x * globalMotionSearchMaxDispatchSize.y);
for (int level = 0; level < OpticalFlow.OpticalFlowMaxPyramidLevels; ++level)
{
CreateDoubleBufferedResource(OpticalFlowInputLevels[level], $"OPTICALFLOW_OpticalFlowInputLevel{level}-", opticalFlowInputTextureSize, GraphicsFormat.R8_UInt);
CreateDoubleBufferedResource(OpticalFlowLevels[level], $"OPTICALFLOW_OpticalFlowLevel{level}-", opticalFlowTextureSize, GraphicsFormat.R16G16_SInt);
opticalFlowTextureSize = NextLevelSize(opticalFlowTextureSize);
opticalFlowInputTextureSize = new Vector2Int(opticalFlowInputTextureSize.x >> 1, opticalFlowInputTextureSize.y >> 1);
}
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);
}
public void Destroy()
{
DestroyResource(ref OpticalFlowSCDTemp);
DestroyResource(ref OpticalFlowSCDPreviousHistogram);
DestroyResource(ref OpticalFlowSCDHistogram);
for (int level = 0; level < OpticalFlow.OpticalFlowMaxPyramidLevels; ++level)
{
DestroyResource(OpticalFlowLevels[level]);
DestroyResource(OpticalFlowInputLevels[level]);
}
}
private static Vector2Int NextLevelSize(Vector2Int size)
{
return new Vector2Int(AlignUp(size.x, 2) / 2, AlignUp(size.y, 2) / 2);
}
private static int AlignUp(int x, int y)
{
return (x + (y - 1)) & ~(y - 1);
}
private static RenderTexture CreateResource(string name, Vector2Int size, GraphicsFormat format)
{
var rt = new RenderTexture(size.x, size.y, 0, format) { name = name, enableRandomWrite = true };
rt.Create();
return rt;
}
private static void CreateDoubleBufferedResource(RenderTexture[] resource, string name, Vector2Int size, GraphicsFormat format)
{
for (int i = 0; i < 2; ++i)
{
resource[i] = new RenderTexture(size.x, size.y, 0, format) { name = name + (i + 1), enableRandomWrite = true };
resource[i].Create();
}
}
private static void DestroyResource(ref RenderTexture resource)
{
if (resource == null)
return;
resource.Release();
resource = null;
}
private static void DestroyResource(RenderTexture[] resource)
{
for (int i = 0; i < resource.Length; ++i)
DestroyResource(ref resource[i]);
}
}
}