From 20f9f5efe6b41f89893939f19b6a42b4f4d2b9c3 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Thu, 18 Jul 2024 14:57:49 +0200 Subject: [PATCH] Rewrote the entire upscaler plugin system so that it should be hot-swappable. FSR2 native wrapper is still a work-in-progress but also fuck that thing. --- .../Upscalers/FSR2WrapperUpscaler.cs | 63 ++++-- .../Upscalers/FSR3UpscalerPlugin.cs | 146 ++++---------- .../RenderPass/Upscalers/UpscalerPlugin.cs | 185 ++++++++++++++---- 3 files changed, 232 insertions(+), 162 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2WrapperUpscaler.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2WrapperUpscaler.cs index 049fcb66..82229bec 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2WrapperUpscaler.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR2WrapperUpscaler.cs @@ -1,6 +1,6 @@ using System; -#if UNITY_STANDALONE_WIN +#if UNITY_STANDALONE_WIN && false namespace UnityEngine.Rendering.HighDefinition.AMD.FSR2Wrapper { /// @@ -11,19 +11,40 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR2Wrapper { public override string name => "FSR 2.1"; - public override bool isSupported => IsLoaded(); + public override bool isSupported => UnityEngine.AMD.AMDUnityPlugin.IsLoaded(); - public override bool Load() => UnityEngine.AMD.AMDUnityPlugin.Load(); - - public override bool IsLoaded() => UnityEngine.AMD.AMDUnityPlugin.IsLoaded(); + public override bool Load() + { + if (!UnityEngine.AMD.AMDUnityPlugin.Load()) + return false; - public override GraphicsDevice CreateGraphicsDevice() => new FSR2WrappedGraphicsDevice(UnityEngine.AMD.GraphicsDevice.CreateGraphicsDevice()); + if (UnityEngine.AMD.GraphicsDevice.device == null) + UnityEngine.AMD.GraphicsDevice.CreateGraphicsDevice(); - public override void DestroyGraphicsDevice() { } // Noop, native plugin does not allow clearing the graphics device + return UnityEngine.AMD.GraphicsDevice.device != null; + } - public override GraphicsDevice device => new FSR2WrappedGraphicsDevice(UnityEngine.AMD.GraphicsDevice.device); + public override bool IsLoaded() => UnityEngine.AMD.AMDUnityPlugin.IsLoaded() && UnityEngine.AMD.GraphicsDevice.device != null; - public override uint version => UnityEngine.AMD.GraphicsDevice.version; + public override UpscalerContext CreateContext(in FSR2CommandInitializationData initSettings) + { + throw new NotImplementedException(); + } + + public override void DestroyContext(UpscalerContext context) + { + throw new NotImplementedException(); + } + + public override bool GetRenderResolutionFromQualityMode(FSR2Quality qualityMode, uint displayWidth, uint displayHeight, out uint renderWidth, out uint renderHeight) + { + return UnityEngine.AMD.GraphicsDevice.device.GetRenderResolutionFromQualityMode((UnityEngine.AMD.FSR2Quality)qualityMode, displayWidth, displayHeight, out renderWidth, out renderHeight); + } + + public override float GetUpscaleRatioFromQualityMode(FSR2Quality qualityMode) + { + return UnityEngine.AMD.GraphicsDevice.device.GetUpscaleRatioFromQualityMode((UnityEngine.AMD.FSR2Quality)qualityMode); + } } public class FSR2WrappedGraphicsDevice: GraphicsDevice @@ -64,22 +85,21 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR2Wrapper } } - public class FSR2WrappedContext : FSR2Context + public class FSR2WrappedContext : UpscalerContext { - internal readonly UnityEngine.AMD.FSR2Context WrappedContext; - - private FSR2CommandInitializationData _initData; - public override ref FSR2CommandInitializationData initData => ref _initData; - - private FSR2CommandExecutionData _executeData; - public override ref FSR2CommandExecutionData executeData => ref _executeData; + private readonly FSR2CommandInitializationData _initData; + private UnityEngine.AMD.FSR2Context _wrappedContext; - internal FSR2WrappedContext(UnityEngine.AMD.FSR2Context wrappedContext, in FSR2CommandInitializationData initData) + internal FSR2WrappedContext(in FSR2CommandInitializationData initData) { - WrappedContext = wrappedContext; _initData = initData; } + internal void Init(UnityEngine.AMD.GraphicsDevice graphicsDevice) + { + _wrappedContext = graphicsDevice.CreateFeature() + } + internal void SyncExecuteData() { WrappedContext.executeData.jitterOffsetX = _executeData.jitterOffsetX; @@ -97,6 +117,11 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR2Wrapper WrappedContext.executeData.cameraFar = _executeData.cameraFar; WrappedContext.executeData.cameraFovAngleVertical = _executeData.cameraFovAngleVertical; } + + public override void Execute(CommandBuffer cmd, in FSR2CommandExecutionData executeData, in FSR2TextureTable textures) + { + throw new NotImplementedException(); + } } internal static class FSR2WrapperExtensions diff --git a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR3UpscalerPlugin.cs b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR3UpscalerPlugin.cs index 02f1b519..3688a8b6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR3UpscalerPlugin.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/Upscalers/FSR3UpscalerPlugin.cs @@ -9,55 +9,13 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR3 /// public class FSR3UpscalerPlugin: UpscalerPlugin { - private static FSR3GraphicsDevice sGraphicsDeviceInstance; - + private Fsr3UpscalerAssets _assets; + public override string name => "FSR 3.0"; public override bool isSupported => SystemInfo.supportsComputeShaders; - public override bool Load() => true; - - public override bool IsLoaded() => true; - - public override GraphicsDevice CreateGraphicsDevice() - { - if (sGraphicsDeviceInstance != null) - { - sGraphicsDeviceInstance.Shutdown(); - sGraphicsDeviceInstance.Initialize(); - return sGraphicsDeviceInstance; - } - - var graphicsDevice = new FSR3GraphicsDevice(); - if (graphicsDevice.Initialize()) - { - sGraphicsDeviceInstance = graphicsDevice; - return graphicsDevice; - } - - Debug.LogWarning("Failed to initialize FSR3 Graphics Device"); - return null; - } - - public override void DestroyGraphicsDevice() - { - if (sGraphicsDeviceInstance != null) - { - sGraphicsDeviceInstance.Shutdown(); - sGraphicsDeviceInstance = null; - } - } - - public override GraphicsDevice device => sGraphicsDeviceInstance; - } - - public class FSR3GraphicsDevice : GraphicsDevice - { - private readonly Stack _contextPool = new(); - - private Fsr3UpscalerAssets _assets; - - internal bool Initialize() + public override bool Load() { if (_assets != null) return true; @@ -66,37 +24,18 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR3 return _assets != null; } - internal void Shutdown() - { - foreach (var context in _contextPool) - { - context.Reset(); - } - - if (_assets != null) - { - Resources.UnloadAsset(_assets); - _assets = null; - } - } + public override bool IsLoaded() => _assets != null; - public override FSR2Context CreateFeature(CommandBuffer cmd, in FSR2CommandInitializationData initSettings) + public override UpscalerContext CreateContext(in FSR2CommandInitializationData initSettings) { - var context = _contextPool.Count != 0 ? _contextPool.Pop() : new FSR3Context(); - context.Init(initSettings, _assets); + var context = new FSR3UpscalerContext(in initSettings); + context.Init(_assets); return context; } - public override void DestroyFeature(CommandBuffer cmd, FSR2Context fsrContext) + public override void DestroyContext(UpscalerContext context) { - var context = (FSR3Context)fsrContext; - context.Reset(); - _contextPool.Push(context); - } - - public override void ExecuteFSR2(CommandBuffer cmd, FSR2Context fsrContext, in FSR2TextureTable textures) - { - ((FSR3Context)fsrContext).Draw(cmd, in textures); + ((FSR3UpscalerContext)context).Destroy(); } public override bool GetRenderResolutionFromQualityMode(FSR2Quality qualityMode, uint displayWidth, uint displayHeight, out uint renderWidth, out uint renderHeight) @@ -113,50 +52,45 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR3 } } - public class FSR3Context : FSR2Context + public class FSR3UpscalerContext : UpscalerContext { - private FSR2CommandInitializationData _initData; - public override ref FSR2CommandInitializationData initData => ref _initData; - - private FSR2CommandExecutionData _executeData; - public override ref FSR2CommandExecutionData executeData => ref _executeData; - private readonly Fsr3UpscalerContext _context = new(); private readonly Fsr3Upscaler.DispatchDescription _dispatchDescription = new(); + private readonly FSR2CommandInitializationData _initData; - internal void Init(in FSR2CommandInitializationData initSettings, Fsr3UpscalerAssets assets) + internal FSR3UpscalerContext(in FSR2CommandInitializationData initSettings) { _initData = initSettings; + } + internal void Init(Fsr3UpscalerAssets assets) + { Fsr3Upscaler.InitializationFlags flags = Fsr3Upscaler.InitializationFlags.EnableFP16Usage; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableHighDynamicRange)) flags |= Fsr3Upscaler.InitializationFlags.EnableHighDynamicRange; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableDisplayResolutionMotionVectors)) flags |= Fsr3Upscaler.InitializationFlags.EnableDisplayResolutionMotionVectors; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableMotionVectorsJitterCancellation)) flags |= Fsr3Upscaler.InitializationFlags.EnableMotionVectorsJitterCancellation; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.DepthInverted)) flags |= Fsr3Upscaler.InitializationFlags.EnableDepthInverted; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableDepthInfinite)) flags |= Fsr3Upscaler.InitializationFlags.EnableDepthInfinite; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableAutoExposure)) flags |= Fsr3Upscaler.InitializationFlags.EnableAutoExposure; - if (initSettings.GetFlag(FfxFsr2InitializationFlags.EnableDynamicResolution)) flags |= Fsr3Upscaler.InitializationFlags.EnableDynamicResolution; - - //Debug.Log($"Initializing FSR3 with max render size: {initSettings.maxRenderSizeWidth}x{initSettings.maxRenderSizeHeight}, display size: {initSettings.displaySizeWidth}x{initSettings.displaySizeHeight}, flags: {flags}"); + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableHighDynamicRange)) flags |= Fsr3Upscaler.InitializationFlags.EnableHighDynamicRange; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDisplayResolutionMotionVectors)) flags |= Fsr3Upscaler.InitializationFlags.EnableDisplayResolutionMotionVectors; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableMotionVectorsJitterCancellation)) flags |= Fsr3Upscaler.InitializationFlags.EnableMotionVectorsJitterCancellation; + if (_initData.GetFlag(FfxFsr2InitializationFlags.DepthInverted)) flags |= Fsr3Upscaler.InitializationFlags.EnableDepthInverted; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDepthInfinite)) flags |= Fsr3Upscaler.InitializationFlags.EnableDepthInfinite; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableAutoExposure)) flags |= Fsr3Upscaler.InitializationFlags.EnableAutoExposure; + if (_initData.GetFlag(FfxFsr2InitializationFlags.EnableDynamicResolution)) flags |= Fsr3Upscaler.InitializationFlags.EnableDynamicResolution; + + Debug.Log($"Initializing FSR3 with max render size: {_initData.maxRenderSizeWidth}x{_initData.maxRenderSizeHeight}, display size: {_initData.displaySizeWidth}x{_initData.displaySizeHeight}, flags: {flags}"); _context.Create(new Fsr3Upscaler.ContextDescription { - DisplaySize = new Vector2Int((int)initSettings.displaySizeWidth, (int)initSettings.displaySizeHeight), - MaxRenderSize = new Vector2Int((int)initSettings.maxRenderSizeWidth, (int)initSettings.maxRenderSizeHeight), + 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 Reset() + internal void Destroy() { _context.Destroy(); - - _initData = new FSR2CommandInitializationData(); - _executeData = new FSR2CommandExecutionData(); } - internal void Draw(CommandBuffer cmd, in FSR2TextureTable textures) + public override void Execute(CommandBuffer cmd, in FSR2CommandExecutionData executeData, in FSR2TextureTable textures) { _dispatchDescription.Color = new ResourceView(textures.colorInput); _dispatchDescription.Depth = new ResourceView(textures.depth); @@ -166,18 +100,18 @@ namespace UnityEngine.Rendering.HighDefinition.AMD.FSR3 _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.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 _context.Dispatch(_dispatchDescription, cmd); 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 2e8cecbe..55ba79f9 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 @@ -10,7 +10,7 @@ namespace UnityEngine.Rendering.HighDefinition.AMD private static readonly List AvailablePlugins = new() { new FSR3.FSR3UpscalerPlugin(), -#if UNITY_STANDALONE_WIN +#if UNITY_STANDALONE_WIN && false new FSR2Wrapper.FSR2WrapperUpscaler(), #endif }; @@ -19,7 +19,7 @@ namespace UnityEngine.Rendering.HighDefinition.AMD public static bool Load() => ActivePlugin.Load(); - public static bool IsLoaded() => ActivePlugin.IsLoaded(); + public static bool IsLoaded() => ActivePlugin.IsLoaded() || ActivePlugin.isSupported; /// /// Get the list of available upscaler plugins, as a read-only list. @@ -71,70 +71,181 @@ namespace UnityEngine.Rendering.HighDefinition.AMD if (newPlugin == ActivePlugin) return true; + + if (!newPlugin.IsLoaded() && !newPlugin.Load()) + return false; - // If HDRP has previously created a graphics device, then it'll expect that to remain in place. - // Hence, make sure we automatically create a graphics device for the new plugin. - if (ActivePlugin != null && ActivePlugin.device != null) - { - var newDevice = newPlugin.CreateGraphicsDevice(); - if (newDevice == null) - return false; - - ActivePlugin.DestroyGraphicsDevice(); - // TODO do we need to create a new "Feature" as well? Does HDRP cache this anywhere? - } + // Hot-swap the upscaler contexts, so HDRP can keep calling the same FSR2Contexts without knowing the underlying implementation has changed. + GraphicsDevice.device.RecreateFeatures(ActivePlugin, newPlugin); ActivePlugin = newPlugin; return true; } } - public abstract class UpscalerPlugin + public class GraphicsDevice { - public abstract string name { get; } - - public abstract bool isSupported { get; } - - public abstract bool Load(); + private static GraphicsDevice sGraphicsDevice = null; - public abstract bool IsLoaded(); - - public abstract GraphicsDevice CreateGraphicsDevice(); + public static GraphicsDevice device => sGraphicsDevice; - public abstract void DestroyGraphicsDevice(); + public static uint version => 0x00; - public abstract GraphicsDevice device { get; } + private readonly HashSet _contexts = new(); + + public static GraphicsDevice CreateGraphicsDevice() + { + // Lazy initialization of the plugin, because HDRP fails to call AMDUnityPlugin.Load() itself + UpscalerPlugin plugin = AMDUnityPlugin.ActivePlugin; + if (plugin != null && !plugin.IsLoaded()) + { + if (!plugin.Load()) + { + Debug.LogWarning("Failed to initialize upscaler plugin"); + return null; + } + } + + if (sGraphicsDevice != null) + { + sGraphicsDevice.Shutdown(); + sGraphicsDevice.Initialize(); + return sGraphicsDevice; + } + + GraphicsDevice graphicsDevice = new GraphicsDevice(); + if (graphicsDevice.Initialize()) + { + sGraphicsDevice = graphicsDevice; + return graphicsDevice; + } + + Debug.LogWarning("Failed to initialize upscaler GraphicsDevice"); + return null; + } + + private bool Initialize() + { + return true; + } + + private void Shutdown() + { + } - public virtual uint version => 0x00; + internal void RecreateFeatures(UpscalerPlugin oldPlugin, UpscalerPlugin newPlugin) + { + foreach (FSR2Context context in _contexts) + { + context.Destroy(oldPlugin); + context.Create(newPlugin); + } + } + + public FSR2Context CreateFeature(CommandBuffer cmd, in FSR2CommandInitializationData initSettings) + { + FSR2Context context = new FSR2Context(in initSettings); + if (!context.Create(AMDUnityPlugin.ActivePlugin)) + return null; + + _contexts.Add(context); + return context; + } + + public void DestroyFeature(CommandBuffer cmd, FSR2Context fsrContext) + { + fsrContext.Destroy(AMDUnityPlugin.ActivePlugin); + _contexts.Remove(fsrContext); + } + + public void ExecuteFSR2(CommandBuffer cmd, FSR2Context fsrContext, in FSR2TextureTable textures) + { + fsrContext.Execute(cmd, textures); + } + + public bool GetRenderResolutionFromQualityMode(FSR2Quality qualityMode, uint displayWidth, uint displayHeight, out uint renderWidth, out uint renderHeight) + { + UpscalerPlugin plugin = AMDUnityPlugin.ActivePlugin; + if (plugin == null) + { + renderWidth = displayWidth; + renderHeight = displayHeight; + return false; + } + + return plugin.GetRenderResolutionFromQualityMode(qualityMode, displayWidth, displayHeight, out renderWidth, out renderHeight); + } + + public float GetUpscaleRatioFromQualityMode(FSR2Quality qualityMode) + { + UpscalerPlugin plugin = AMDUnityPlugin.ActivePlugin; + if (plugin == null) + { + return 1.0f; + } + + return plugin.GetUpscaleRatioFromQualityMode(qualityMode); + } } - public abstract class GraphicsDevice + public class FSR2Context { - public static GraphicsDevice device => AMDUnityPlugin.ActivePlugin.device; + private UpscalerContext _wrappedContext; - public static uint version => AMDUnityPlugin.ActivePlugin.version; + private FSR2CommandInitializationData _initData; + public ref FSR2CommandInitializationData initData => ref _initData; - public static GraphicsDevice CreateGraphicsDevice() + private FSR2CommandExecutionData _executeData; + public ref FSR2CommandExecutionData executeData => ref _executeData; + + public FSR2Context(in FSR2CommandInitializationData initSettings) { - return AMDUnityPlugin.ActivePlugin.CreateGraphicsDevice(); + _initData = initSettings; + } + + public bool Create(UpscalerPlugin plugin) + { + _wrappedContext = plugin?.CreateContext(in _initData); + return _wrappedContext != null; + } + + public void Destroy(UpscalerPlugin plugin) + { + if (_wrappedContext == null) + return; + + plugin?.DestroyContext(_wrappedContext); + _wrappedContext = null; } - public abstract FSR2Context CreateFeature(CommandBuffer cmd, in FSR2CommandInitializationData initSettings); + public void Execute(CommandBuffer cmd, in FSR2TextureTable textures) + { + _wrappedContext?.Execute(cmd, in executeData, in textures); + } + } + + public abstract class UpscalerPlugin + { + public abstract string name { get; } + + public abstract bool isSupported { get; } + + public abstract bool Load(); - public abstract void DestroyFeature(CommandBuffer cmd, FSR2Context fsrContext); + public abstract bool IsLoaded(); - public abstract void ExecuteFSR2(CommandBuffer cmd, FSR2Context fsrContext, in FSR2TextureTable textures); + public abstract UpscalerContext CreateContext(in FSR2CommandInitializationData initSettings); + public abstract void DestroyContext(UpscalerContext context); + public abstract bool GetRenderResolutionFromQualityMode(FSR2Quality qualityMode, uint displayWidth, uint displayHeight, out uint renderWidth, out uint renderHeight); public abstract float GetUpscaleRatioFromQualityMode(FSR2Quality qualityMode); } - public abstract class FSR2Context + public abstract class UpscalerContext { - public abstract ref FSR2CommandInitializationData initData { get; } - - public abstract ref FSR2CommandExecutionData executeData { get; } + public abstract void Execute(CommandBuffer cmd, in FSR2CommandExecutionData executeData, in FSR2TextureTable textures); } public struct FSR2CommandInitializationData