diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs new file mode 100644 index 00000000..be5cd9f4 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs @@ -0,0 +1,121 @@ +using System.Collections.Generic; +using FidelityFX; + +namespace UnityEngine.Rendering.HighDefinition.AMD.FSR2 +{ + /// + /// Custom upscaler plugin that uses the open source port of FSR2 to Unity. + /// This eschews using native plugins, instead using portable code that will work on any platform that supports compute shaders. + /// + public class FSR2UpscalerPlugin: UpscalerPlugin + { + private Fsr2Assets _assets; + + public override string name => "FSR 2.2"; + + public override bool isSupported => SystemInfo.supportsComputeShaders; + + public override bool Load() + { + if (_assets != null) + return true; + + _assets = Resources.Load("FSR2 Assets"); + return _assets != null; + } + + public override bool IsLoaded() => _assets != null; + + public override UpscalerContext CreateContext(in FSR2CommandInitializationData initSettings) + { + var context = new FSR2UpscalerContext(in initSettings); + context.Init(_assets); + return context; + } + + public override void DestroyContext(UpscalerContext context) + { + ((FSR2UpscalerContext)context).Destroy(); + } + + public override bool GetRenderResolutionFromQualityMode(FSR2Quality qualityMode, uint displayWidth, uint displayHeight, out uint renderWidth, out uint renderHeight) + { + Fsr3Upscaler.GetRenderResolutionFromQualityMode(out int rw, out int rh, (int)displayWidth, (int)displayHeight, (Fsr3Upscaler.QualityMode)((int)qualityMode + 2)); + renderWidth = (uint)rw; + renderHeight = (uint)rh; + return true; + } + + public override float GetUpscaleRatioFromQualityMode(FSR2Quality qualityMode) + { + return Fsr3Upscaler.GetUpscaleRatioFromQualityMode((Fsr3Upscaler.QualityMode)((int)qualityMode + 2)); + } + } + + public class FSR2UpscalerContext : UpscalerContext + { + private readonly Fsr2Context _context = new(); + private readonly Fsr2.DispatchDescription _dispatchDescription = new(); + private readonly FSR2CommandInitializationData _initData; + + internal FSR2UpscalerContext(in FSR2CommandInitializationData initSettings) + { + _initData = initSettings; + } + + internal void Init(Fsr2Assets assets) + { + Fsr2.InitializationFlags flags = Fsr2.InitializationFlags.EnableFP16Usage; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableHighDynamicRange)) flags |= Fsr2.InitializationFlags.EnableHighDynamicRange; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDisplayResolutionMotionVectors)) flags |= Fsr2.InitializationFlags.EnableDisplayResolutionMotionVectors; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableMotionVectorsJitterCancellation)) flags |= Fsr2.InitializationFlags.EnableMotionVectorsJitterCancellation; + if (_initData.GetFlag(FfxFsr2InitializationFlags.DepthInverted)) flags |= Fsr2.InitializationFlags.EnableDepthInverted; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDepthInfinite)) flags |= Fsr2.InitializationFlags.EnableDepthInfinite; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableAutoExposure)) flags |= Fsr2.InitializationFlags.EnableAutoExposure; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDynamicResolution)) flags |= Fsr2.InitializationFlags.EnableDynamicResolution; + + Debug.Log($"Initializing FSR2 with max render size: {_initData.maxRenderSizeWidth}x{_initData.maxRenderSizeHeight}, display size: {_initData.displaySizeWidth}x{_initData.displaySizeHeight}, flags: {flags}"); + + _context.Create(new Fsr2.ContextDescription + { + DisplaySize = new Vector2Int((int)_initData.displaySizeWidth, (int)_initData.displaySizeHeight), + MaxRenderSize = new Vector2Int((int)_initData.maxRenderSizeWidth, (int)_initData.maxRenderSizeHeight), + Flags = flags, + Shaders = assets.shaders, + }); + } + + internal void Destroy() + { + _context.Destroy(); + } + + public override void Execute(CommandBuffer cmd, in FSR2CommandExecutionData executeData, in FSR2TextureTable textures) + { + _dispatchDescription.Color = new ResourceView(textures.colorInput); + _dispatchDescription.Depth = new ResourceView(textures.depth); + _dispatchDescription.MotionVectors = new ResourceView(textures.motionVectors); + _dispatchDescription.Exposure = new ResourceView(textures.exposureTexture); + _dispatchDescription.Reactive = new ResourceView(textures.biasColorMask); + _dispatchDescription.TransparencyAndComposition = new ResourceView(textures.transparencyMask); + _dispatchDescription.Output = new ResourceView(textures.colorOutput); + + _dispatchDescription.JitterOffset = new Vector2(executeData.jitterOffsetX, executeData.jitterOffsetY); + _dispatchDescription.MotionVectorScale = new Vector2(executeData.MVScaleX, executeData.MVScaleY); + _dispatchDescription.RenderSize = new Vector2Int((int)executeData.renderSizeWidth, (int)executeData.renderSizeHeight); + _dispatchDescription.InputResourceSize = new Vector2Int((int)executeData.renderSizeWidth, (int)executeData.renderSizeHeight); + _dispatchDescription.EnableSharpening = executeData.enableSharpening != 0; + _dispatchDescription.Sharpness = executeData.sharpness; + _dispatchDescription.FrameTimeDelta = executeData.frameTimeDelta / 1000f; + _dispatchDescription.PreExposure = executeData.preExposure; + _dispatchDescription.Reset = executeData.reset != 0; + _dispatchDescription.CameraNear = executeData.cameraNear; + _dispatchDescription.CameraFar = executeData.cameraFar; + _dispatchDescription.CameraFovAngleVertical = executeData.cameraFovAngleVertical; + _dispatchDescription.ViewSpaceToMetersFactor = 1.0f; // 1 unit is 1 meter in Unity + _dispatchDescription.UseTextureArrays = TextureXR.useTexArray && textures.colorInput.dimension == TextureDimension.Tex2DArray; + + _context.Dispatch(_dispatchDescription, cmd); + } + } +} diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs.meta b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs.meta new file mode 100644 index 00000000..fb49886b --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2UpscalerPlugin.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: d1949a73f3cda0f418c91ecd8212668c diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset new file mode 100644 index 00000000..e1c438e1 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset @@ -0,0 +1,23 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: db26e15a33db6ab42a38daab0ba2712f, type: 3} + m_Name: FSR2 Assets + m_EditorClassIdentifier: + shaders: + computeLuminancePyramidPass: {fileID: 7200000, guid: 04c3480675e29a340808141e68d4cc8b, type: 3} + reconstructPreviousDepthPass: {fileID: 7200000, guid: 5060dfafe45aa67459629186ceb7464e, type: 3} + depthClipPass: {fileID: 7200000, guid: b207de122e2c4b844b89dcd7c5c77c80, type: 3} + lockPass: {fileID: 7200000, guid: 20b7864a7e7258946aaf0f1996febad3, type: 3} + accumulatePass: {fileID: 7200000, guid: 7e791d69a5be98247a93b63897bc64df, type: 3} + sharpenPass: {fileID: 7200000, guid: 40815651f0f5d994cb73da9816a7ff9b, type: 3} + autoGenReactivePass: {fileID: 7200000, guid: 67ee1b32ca5e4234db9f06984c783dee, type: 3} + tcrAutoGenPass: {fileID: 7200000, guid: f8b1c27fb6a544b43b38903592240500, type: 3} diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset.meta b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset.meta new file mode 100644 index 00000000..41e9aa1f --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/Resources/FSR2 Assets.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8e31014ba9715c84d98f64c0cbe4cbad +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/UpscalerPlugin.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/UpscalerPlugin.cs index 55ba79f9..f99512b2 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/UpscalerPlugin.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/UpscalerPlugin.cs @@ -9,6 +9,7 @@ namespace UnityEngine.Rendering.HighDefinition.AMD { private static readonly List AvailablePlugins = new() { + new FSR2.FSR2UpscalerPlugin(), new FSR3.FSR3UpscalerPlugin(), #if UNITY_STANDALONE_WIN && false new FSR2Wrapper.FSR2WrapperUpscaler(),