Browse Source

Allow input textures to be set outside of FSR2 context dispatch, opening up new avenues for optimizations.

Started with setting motion vectors and output RT directly from the Unity command buffer, blitting to the destination RT only when necessary.
mac-autoexp
Nico de Poel 3 years ago
parent
commit
776700e837
  1. 45
      Assets/Scripts/Fsr2Controller.cs
  2. 43
      Assets/Scripts/Fsr2Pipeline.cs

45
Assets/Scripts/Fsr2Controller.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using FidelityFX;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
/// <summary>
@ -100,17 +101,32 @@ public class Fsr2Controller : MonoBehaviour
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
var renderBuffer = gameCamera.targetTexture;
var commandBuffer = new CommandBuffer { name = "FSR2" };
int motionVectorsId = Shader.PropertyToID("r_input_motion_vectors");
int upscaledOutputId = Shader.PropertyToID("rw_upscaled_output");
// I hate having to allocate extra RTs just to duplicate already existing Unity render buffers, but AFAIK there is no way to directly address motion vectors from code
var motionVectors = RenderTexture.GetTemporary(renderBuffer.width, renderBuffer.height, 0, RenderTextureFormat.RGHalf);
Graphics.Blit(renderBuffer, motionVectors, CopyMotionVectorsMaterial);
// TODO: or can we? Look at RenderTargetIdentifier.MotionVectors with SetGlobalTexture!! (Possibly in gameCamera OnRenderImage)
commandBuffer.GetTemporaryRT(motionVectorsId, renderBuffer.width, renderBuffer.height, 0, default, RenderTextureFormat.RGHalf);
commandBuffer.Blit(renderBuffer, motionVectorsId, CopyMotionVectorsMaterial);
// TODO: if `dest` is null, we are rendering straight to the backbuffer and should use a temporary RT as the output buffer for FSR2
// TODO: if `dest` it NOT null, we have more image effects lined up after this one, and we should be able to have FSR2 output straight to `dest` without an intermediary temp RT
if (dest != null)
{
// We have more image effects lined up after this, so FSR2 can output straight to the intermediate render texture
// TODO: we should probably use a shader to include depth & motion vectors into the output
commandBuffer.SetGlobalTexture(upscaledOutputId, dest);
}
else
{
// We are rendering to the backbuffer, so we need a temporary render texture for FSR2 to output to
commandBuffer.GetTemporaryRT(upscaledOutputId, DisplaySize.x, DisplaySize.y, 0, default, GraphicsFormat.R16G16B16A16_SFloat, 1, true);
}
_dispatchDescription.ColorDepth = renderBuffer;
_dispatchDescription.MotionVectors = motionVectors;
_dispatchDescription.Output = _upscaledOutput;
_dispatchDescription.MotionVectors = null;
_dispatchDescription.Output = null;
_dispatchDescription.Exposure = null;
_dispatchDescription.Reactive = null;
_dispatchDescription.PreExposure = 0;
@ -127,13 +143,22 @@ public class Fsr2Controller : MonoBehaviour
_dispatchDescription.Reset = reset;
reset = false;
_context.Dispatch(_dispatchDescription);
_context.Dispatch(_dispatchDescription, commandBuffer);
// Output upscaled image to screen
// TODO: we should probably use a shader to include depth & motion vectors into the output
// TODO: if `dest` is null, we likely don't care about the depth & motion vectors anymore
Graphics.Blit(_upscaledOutput, dest);
if (dest == null)
{
commandBuffer.Blit(upscaledOutputId, dest);
commandBuffer.ReleaseTemporaryRT(upscaledOutputId);
}
commandBuffer.ReleaseTemporaryRT(motionVectorsId);
Graphics.ExecuteCommandBuffer(commandBuffer);
commandBuffer.Release();
RenderTexture.ReleaseTemporary(motionVectors);
// Shut up the Unity warning about not writing to the destination texture
Graphics.SetRenderTarget(dest);
}
}

43
Assets/Scripts/Fsr2Pipeline.cs

@ -181,8 +181,11 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
if (dispatchParams.ColorDepth != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
}
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavExposureMip5, Resources.SceneLuminance, 5);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, Resources.AutoExposure);
@ -204,9 +207,15 @@ namespace FidelityFX
public override void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int frameIndex, int dispatchX, int dispatchY)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Depth);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
if (dispatchParams.ColorDepth != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Depth);
}
if (dispatchParams.MotionVectors != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
}
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
@ -231,9 +240,15 @@ namespace FidelityFX
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvReactiveMask, dispatchParams.Reactive);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvTransparencyAndCompositionMask, Resources.DefaultReactive); // Default reactive mask, as we don't support TCR (yet)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvPrevDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex ^ 1]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Depth);
if (dispatchParams.MotionVectors != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
}
if (dispatchParams.ColorDepth != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Color);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputDepth, dispatchParams.ColorDepth, 0, RenderTextureSubElement.Depth);
}
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
@ -274,7 +289,7 @@ namespace FidelityFX
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
if ((ContextDescription.Flags & Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors) == 0)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvDilatedMotionVectors, Resources.DilatedMotionVectors[frameIndex]);
else
else if (dispatchParams.MotionVectors != null)
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputMotionVectors, dispatchParams.MotionVectors);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInternalUpscaled, Resources.InternalUpscaled[frameIndex ^ 1]);
@ -287,7 +302,10 @@ namespace FidelityFX
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavLockStatus, Resources.LockStatus[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
if (dispatchParams.Output != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
}
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavLumaHistory, Resources.LumaHistory[frameIndex]);
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
@ -346,7 +364,10 @@ namespace FidelityFX
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputExposure, dispatchParams.Exposure);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvRcasInput, Resources.InternalUpscaled[frameIndex]);
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
if (dispatchParams.Output != null)
{
commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavUpscaledOutput, dispatchParams.Output);
}
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf<Fsr2.RcasConstants>());

Loading…
Cancel
Save