diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs index e80188f..682f2d2 100644 --- a/Assets/Scripts/Fsr2Controller.cs +++ b/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; /// @@ -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); } } diff --git a/Assets/Scripts/Fsr2Pipeline.cs b/Assets/Scripts/Fsr2Pipeline.cs index f04bd10..e522bbe 100644 --- a/Assets/Scripts/Fsr2Pipeline.cs +++ b/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()); @@ -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()); @@ -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()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbRcas, _rcasConstants, 0, Marshal.SizeOf());