diff --git a/Assets/Scripts/Fsr2.cs b/Assets/Scripts/Fsr2.cs index 00e491b..0a935b5 100644 --- a/Assets/Scripts/Fsr2.cs +++ b/Assets/Scripts/Fsr2.cs @@ -130,12 +130,6 @@ namespace FidelityFX EnableDebugChecking = 1 << 8, } - public enum MessageType - { - Error = 0, - Warning = 1, - } - public struct ContextDescription { public InitializationFlags Flags; diff --git a/Assets/Scripts/Fsr2Callbacks.cs b/Assets/Scripts/Fsr2Callbacks.cs index e43347b..5fd5a3a 100644 --- a/Assets/Scripts/Fsr2Callbacks.cs +++ b/Assets/Scripts/Fsr2Callbacks.cs @@ -8,19 +8,6 @@ namespace FidelityFX /// public class Fsr2Callbacks { - public virtual void Message(Fsr2.MessageType type, string message) - { - switch (type) - { - case Fsr2.MessageType.Warning: - Debug.LogWarning(message); - break; - case Fsr2.MessageType.Error: - Debug.LogError(message); - break; - } - } - public virtual Shader LoadShader(string name) { return Resources.Load(name); diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index c777d04..8bba114 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -113,7 +113,10 @@ namespace FidelityFX public void Dispatch(Fsr2.DispatchDescription dispatchParams, CommandBuffer commandBuffer) { - // TODO: validation & debug checking + if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableDebugChecking) != 0) + { + DebugCheckDispatch(dispatchParams); + } if (_firstExecution) { @@ -362,6 +365,103 @@ namespace FidelityFX } } + private void DebugCheckDispatch(Fsr2.DispatchDescription dispatchParams) + { + if (dispatchParams.Exposure.HasValue && (_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) + { + Debug.LogWarning("Exposure resource provided, however auto exposure flag is present"); + } + + if (Mathf.Abs(dispatchParams.JitterOffset.x) > 1.0f || Mathf.Abs(dispatchParams.JitterOffset.y) > 1.0f) + { + Debug.LogWarning("JitterOffset contains value outside of expected range [-1.0, 1.0]"); + } + + if (dispatchParams.MotionVectorScale.x > _contextDescription.MaxRenderSize.x || dispatchParams.MotionVectorScale.y > _contextDescription.MaxRenderSize.y) + { + Debug.LogWarning("MotionVectorScale contains scale value greater than MaxRenderSize"); + } + + if (dispatchParams.MotionVectorScale.x == 0.0f || dispatchParams.MotionVectorScale.y == 0.0f) + { + Debug.LogWarning("MotionVectorScale contains zero scale value"); + } + + if (dispatchParams.RenderSize.x > _contextDescription.MaxRenderSize.x || dispatchParams.RenderSize.y > _contextDescription.MaxRenderSize.y) + { + Debug.LogWarning("RenderSize is greater than context MaxRenderSize"); + } + + if (dispatchParams.RenderSize.x == 0 || dispatchParams.RenderSize.y == 0) + { + Debug.LogWarning("RenderSize contains zero dimension"); + } + + if (dispatchParams.FrameTimeDelta > 1.0f) + { + Debug.LogWarning("FrameTimeDelta is greater than 1.0f - this value should be seconds (~0.0166 for 60fps)"); + } + + if (dispatchParams.PreExposure == 0.0f) + { + Debug.LogError("PreExposure provided as 0.0f which is invalid"); + } + + bool infiniteDepth = (_contextDescription.Flags & Fsr2.InitializationFlags.EnableDepthInfinite) != 0; + bool inverseDepth = (_contextDescription.Flags & Fsr2.InitializationFlags.EnableDepthInverted) != 0; + + if (inverseDepth) + { + if (dispatchParams.CameraNear < dispatchParams.CameraFar) + { + Debug.LogWarning("EnableDepthInverted flag is present yet CameraNear is less than CameraFar"); + } + + if (infiniteDepth) + { + if (dispatchParams.CameraNear != float.MaxValue) + { + Debug.LogWarning("EnableDepthInfinite and EnableDepthInverted present, yet CameraNear != float.MaxValue"); + } + } + + if (dispatchParams.CameraFar < 0.075f) + { + Debug.LogWarning("EnableDepthInverted present, CameraFar value is very low which may result in depth separation artefacting"); + } + } + else + { + if (dispatchParams.CameraNear > dispatchParams.CameraFar) + { + Debug.LogWarning("CameraNear is greater than CameraFar in non-inverted-depth context"); + } + + if (infiniteDepth) + { + if (dispatchParams.CameraFar != float.MaxValue) + { + Debug.LogWarning("EnableDepthInfinite present, yet CameraFar != float.MaxValue"); + } + } + + if (dispatchParams.CameraNear < 0.075f) + { + Debug.LogWarning("CameraNear value is very low which may result in depth separation artefacting"); + } + } + + if (dispatchParams.CameraFovAngleVertical <= 0.0f) + { + Debug.LogError("CameraFovAngleVertical is 0.0f - this value should be > 0.0f"); + } + + if (dispatchParams.CameraFovAngleVertical > Mathf.PI) + { + Debug.LogError("CameraFovAngleVertical is greater than 180 degrees/PI"); + } + } + /// /// The FSR2 C++ codebase uses floats bitwise converted to ints to pass sharpness parameters to the RCAS shader. /// This is not possible in C# without enabling unsafe code compilation, so to avoid that we instead use a table of precomputed values. diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs index 2a81528..f16b55f 100644 --- a/Assets/Scripts/Fsr2Controller.cs +++ b/Assets/Scripts/Fsr2Controller.cs @@ -64,6 +64,10 @@ namespace FidelityFX if (enableFP16) flags |= Fsr2.InitializationFlags.EnableFP16Usage; +#if UNITY_EDITOR || DEVELOPMENT_BUILD + flags |= Fsr2.InitializationFlags.EnableDebugChecking; +#endif + _displaySize = new Vector2Int(Screen.width, Screen.height); Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, _displaySize.x, _displaySize.y, qualityMode); _renderSize = new Vector2Int(renderWidth, renderHeight); @@ -189,7 +193,7 @@ namespace FidelityFX _dispatchDescription.Reactive = null; _dispatchDescription.TransparencyAndComposition = null; _dispatchDescription.Output = null; - _dispatchDescription.PreExposure = 0; + _dispatchDescription.PreExposure = 1.0f; _dispatchDescription.EnableSharpening = performSharpenPass; _dispatchDescription.Sharpness = sharpness; _dispatchDescription.MotionVectorScale.x = -_renderCamera.pixelWidth; @@ -203,6 +207,12 @@ namespace FidelityFX _dispatchDescription.Reset = _reset; _reset = false; + if (SystemInfo.usesReversedZBuffer) + { + // Swap the near and far clip plane distances as FSR2 expects this when using inverted depth + (_dispatchDescription.CameraNear, _dispatchDescription.CameraFar) = (_dispatchDescription.CameraFar, _dispatchDescription.CameraNear); + } + // Perform custom jittering of the camera's projection matrix according to FSR2's recipe int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderSize.x, _displaySize.x); Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);