Decompiled source of RiskOfRainUpscaling v1.0.1

BepInEx/patchers/RiskOfRainUpscaling/RiskOfRainUpscaling.Preloader.dll

Decompiled 18 hours ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Xander Frangos")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("RiskOfRainUpscaling.Preloader")]
[assembly: AssemblyTitle("RiskOfRainUpscaling.Preloader")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RiskOfRainUpscaling
{
	internal static class NativeApi
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
		internal delegate int InitializeDelegate(string logs, string runtimes, string startupStage);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr EventGetter();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int IntQuery();

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void IntAction(int value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int IntSetter(int value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int FloatSetter(float value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void MarkerAction(int marker, int frame);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal delegate int StringQuery(string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
		internal delegate void StringAction(string value);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int ContextQuery(IntPtr context);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void ContextAction(IntPtr context);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr SceneInputsCreateDelegate(ref SceneInputsDescription description);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr DiagnosticsCreateDelegate(ref DiagnosticsDescription description);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int CaptureArmDelegate(IntPtr context, ref CaptureDescription description);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate IntPtr UpscalerCreateDelegate(ref UpscalerDescription description);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int UpscalerSubmitDelegate(IntPtr context, ref CameraFrame frame);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int OutlineMasksSetter(IntPtr context, IntPtr source, IntPtr target);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int TemporalOutlinesSetter(IntPtr context, IntPtr mask, IntPtr sobel, IntPtr composite);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate int FullResolutionOutlinesSetter(IntPtr context, IntPtr mask, IntPtr objectDepth, IntPtr occlusion, IntPtr sobel, int reversedDepth);

		internal struct Matrix16
		{
			internal float A0;

			internal float A1;

			internal float A2;

			internal float A3;

			internal float B0;

			internal float B1;

			internal float B2;

			internal float B3;

			internal float C0;

			internal float C1;

			internal float C2;

			internal float C3;

			internal float D0;

			internal float D1;

			internal float D2;

			internal float D3;
		}

		internal struct SceneInputsDescription
		{
			internal uint Size;

			internal uint Version;

			internal int Width;

			internal int Height;

			internal IntPtr Depth;
		}

		internal struct UpscalerDescription
		{
			internal uint Size;

			internal uint Version;

			internal int Width;

			internal int Height;

			internal IntPtr SceneInputs;

			internal IntPtr Color;

			internal IntPtr Depth;

			internal IntPtr Motion;

			internal IntPtr Output;

			internal int OutputWidth;

			internal int OutputHeight;

			internal int Quality;

			internal int Placement;
		}

		internal struct CameraFrame
		{
			internal uint Size;

			internal uint Version;

			internal int Frame;

			internal int Reset;

			internal Matrix16 Projection;

			internal Matrix16 InverseProjection;

			internal Matrix16 ClipToPrevious;

			internal Matrix16 PreviousToClip;

			internal float JitterX;

			internal float JitterY;

			internal float MotionScaleX;

			internal float MotionScaleY;

			internal float Near;

			internal float Far;

			internal float Fov;

			internal float Aspect;

			internal float PosX;

			internal float PosY;

			internal float PosZ;

			internal float UpX;

			internal float UpY;

			internal float UpZ;

			internal float RightX;

			internal float RightY;

			internal float RightZ;

			internal float ForwardX;

			internal float ForwardY;

			internal float ForwardZ;

			internal int ReversedDepth;
		}

		internal struct DiagnosticsDescription
		{
			internal uint Size;

			internal uint Version;

			internal int InputWidth;

			internal int InputHeight;

			internal int OutputWidth;

			internal int OutputHeight;

			internal float Near;

			internal float Far;

			internal float DepthRange;

			internal float MotionGain;

			internal int ReversedDepth;

			internal int Reserved;

			internal IntPtr Depth;

			internal IntPtr Motion;

			internal IntPtr DepthPreview;

			internal IntPtr MotionPreview;

			internal IntPtr FinalColor;

			internal IntPtr SceneColor;

			internal IntPtr SceneBeforeHud;
		}

		internal struct CaptureDescription
		{
			internal uint Size;

			internal uint Version;

			internal int UnityFrame;

			internal int Reserved;

			internal IntPtr SceneColor;

			internal IntPtr SceneBeforeHud;

			internal IntPtr Depth;

			internal IntPtr Motion;

			internal IntPtr DepthPreview;

			internal IntPtr MotionPreview;

			internal IntPtr FinalColor;
		}

		internal static InitializeDelegate Initialize;

		internal static IntAction SetLoggingLevel;

		internal static IntQuery GetObservedDeviceCount;

		internal static IntQuery GetPresentationState;

		internal static SceneInputsCreateDelegate SceneInputsCreate;

		internal static EventGetter SceneInputsGetEvent;

		internal static EventGetter SceneInputsGetFrameEvent;

		internal static ContextQuery SceneInputsState;

		internal static ContextAction SceneInputsDestroy;

		internal static UpscalerCreateDelegate UpscalerCreate;

		internal static UpscalerSubmitDelegate UpscalerSubmitFrame;

		internal static EventGetter UpscalerGetEvaluateEvent;

		internal static EventGetter UpscalerGetSharpenEvent;

		internal static EventGetter UpscalerGetFallbackEvent;

		internal static EventGetter UpscalerGetOutlineUpscaleEvent;

		internal static EventGetter UpscalerGetOutlineCompositeEvent;

		internal static EventGetter UpscalerGetOutlineOcclusionEvent;

		internal static EventGetter UpscalerGetOutlineSobelEvent;

		internal static OutlineMasksSetter UpscalerSetOutlineMasks;

		internal static TemporalOutlinesSetter UpscalerSetTemporalOutlines;

		internal static FullResolutionOutlinesSetter UpscalerSetFullResolutionOutlines;

		internal static ContextQuery UpscalerState;

		internal static ContextQuery UpscalerTemporalOutlinesActive;

		internal static ContextQuery UpscalerFullResolutionOutlinesActive;

		internal static ContextQuery UpscalerKind;

		internal static ContextAction UpscalerDestroy;

		internal static IntSetter SetUpscalerBackend;

		internal static IntSetter SetDlssPreset;

		internal static FloatSetter SetSharpness;

		internal static IntAction FrameGenerationSetEnabled;

		internal static IntSetter FrameGenerationSetMultiplier;

		internal static IntSetter ReflexSetFrameLimit;

		internal static IntSetter FramePacerWait;

		internal static IntQuery FrameGenerationState;

		internal static IntQuery FrameGenerationPresentedFrames;

		internal static IntQuery FrameGenerationMultiplier;

		internal static IntQuery FrameGenerationKind;

		internal static IntQuery ReflexFrameLimit;

		internal static IntQuery ReflexGuardWaits;

		internal static EventGetter FrameGenerationGetBeforeHudEvent;

		internal static EventGetter FrameGenerationGetAfterHudEvent;

		internal static MarkerAction FrameGenerationMarker;

		internal static DiagnosticsCreateDelegate DiagnosticsCreate;

		internal static EventGetter DiagnosticsGetEvent;

		internal static EventGetter DiagnosticsGetFinalCopyEvent;

		internal static ContextQuery DiagnosticsState;

		internal static ContextQuery CaptureState;

		internal static ContextAction DiagnosticsDestroy;

		internal static ContextAction CaptureCancel;

		internal static CaptureArmDelegate CaptureArm;

		internal static IntAction ProfilerSetEnabled;

		internal static StringQuery ProfilerRegister;

		internal static StringAction ProfilerSetContext;

		internal static EventGetter ProfilerGetEvent;

		private static IntPtr module;

		internal static string PresentationLabel => ((GetPresentationState != null) ? GetPresentationState() : (-3)) switch
		{
			0 => "Native D3D11", 
			-1 => "Native (bridge unavailable)", 
			-2 => "Bridge failed", 
			1 => "Bridge pending", 
			2 => "D3D12 bridge", 
			_ => "Unavailable", 
		};

		internal static string FrameGenerationLabel
		{
			get
			{
				if (FrameGenerationState == null)
				{
					return "unavailable";
				}
				return FrameGenerationState() switch
				{
					3 => BackendName + " " + FrameGenerationMultiplier() + "x enabled", 
					2 => "waiting for gameplay", 
					1 => "startup pending", 
					-2 => "failed; see native.log", 
					_ => "Off", 
				};
			}
		}

		private static string BackendName => FrameGenerationKind?.Invoke() switch
		{
			1 => "DLSS", 
			2 => "FSR", 
			_ => "", 
		};

		[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern IntPtr LoadLibraryEx(string path, IntPtr file, uint flags);

		[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true)]
		private static extern IntPtr GetProcAddress(IntPtr module, string name);

		internal static string UpscalerName(IntPtr context)
		{
			if (context == IntPtr.Zero || UpscalerKind == null)
			{
				return "";
			}
			return UpscalerKind(context) switch
			{
				1 => "DLSS", 
				2 => "FSR", 
				_ => "pending", 
			};
		}

		internal static void Load(string path)
		{
			if (!(module != IntPtr.Zero))
			{
				module = LoadLibraryEx(Path.GetFullPath(path), IntPtr.Zero, 2304u);
				if (module == IntPtr.Zero)
				{
					throw new Win32Exception(Marshal.GetLastWin32Error(), "Native library load failed: " + path);
				}
				Bind<InitializeDelegate>(out Initialize, "Initialize");
				Bind<IntAction>(out SetLoggingLevel, "SetLoggingLevel");
				Bind<IntQuery>(out GetObservedDeviceCount, "GetObservedDeviceCount");
				Bind<IntQuery>(out GetPresentationState, "GetPresentationState");
				Bind<SceneInputsCreateDelegate>(out SceneInputsCreate, "SceneInputsCreate");
				Bind<EventGetter>(out SceneInputsGetEvent, "SceneInputsGetEvent");
				Bind<EventGetter>(out SceneInputsGetFrameEvent, "SceneInputsGetFrameEvent");
				Bind<ContextQuery>(out SceneInputsState, "SceneInputsState");
				Bind<ContextAction>(out SceneInputsDestroy, "SceneInputsDestroy");
				Bind<UpscalerCreateDelegate>(out UpscalerCreate, "UpscalerCreate");
				Bind<UpscalerSubmitDelegate>(out UpscalerSubmitFrame, "UpscalerSubmitFrame");
				Bind<EventGetter>(out UpscalerGetEvaluateEvent, "UpscalerGetEvaluateEvent");
				Bind<EventGetter>(out UpscalerGetSharpenEvent, "UpscalerGetSharpenEvent");
				Bind<EventGetter>(out UpscalerGetFallbackEvent, "UpscalerGetFallbackEvent");
				Bind<EventGetter>(out UpscalerGetOutlineUpscaleEvent, "UpscalerGetOutlineUpscaleEvent");
				Bind<EventGetter>(out UpscalerGetOutlineCompositeEvent, "UpscalerGetOutlineCompositeEvent");
				Bind<OutlineMasksSetter>(out UpscalerSetOutlineMasks, "UpscalerSetOutlineMasks");
				Bind<TemporalOutlinesSetter>(out UpscalerSetTemporalOutlines, "UpscalerSetTemporalOutlines");
				Bind<FullResolutionOutlinesSetter>(out UpscalerSetFullResolutionOutlines, "UpscalerSetFullResolutionOutlines");
				Bind<EventGetter>(out UpscalerGetOutlineOcclusionEvent, "UpscalerGetOutlineOcclusionEvent");
				Bind<EventGetter>(out UpscalerGetOutlineSobelEvent, "UpscalerGetOutlineSobelEvent");
				Bind<ContextQuery>(out UpscalerState, "UpscalerState");
				Bind<ContextQuery>(out UpscalerTemporalOutlinesActive, "UpscalerTemporalOutlinesActive");
				Bind<ContextQuery>(out UpscalerFullResolutionOutlinesActive, "UpscalerFullResolutionOutlinesActive");
				Bind<ContextQuery>(out UpscalerKind, "UpscalerKind");
				Bind<ContextAction>(out UpscalerDestroy, "UpscalerDestroy");
				Bind<IntSetter>(out SetUpscalerBackend, "SetUpscalerBackend");
				Bind<IntSetter>(out SetDlssPreset, "SetDlssPreset");
				Bind<FloatSetter>(out SetSharpness, "SetSharpness");
				Bind<IntAction>(out FrameGenerationSetEnabled, "FrameGenerationSetEnabled");
				Bind<IntSetter>(out FrameGenerationSetMultiplier, "FrameGenerationSetMultiplier");
				Bind<IntQuery>(out FrameGenerationState, "FrameGenerationState");
				Bind<IntQuery>(out FrameGenerationPresentedFrames, "FrameGenerationPresentedFrames");
				Bind<IntQuery>(out FrameGenerationMultiplier, "FrameGenerationMultiplier");
				Bind<IntQuery>(out FrameGenerationKind, "FrameGenerationKind");
				Bind<EventGetter>(out FrameGenerationGetBeforeHudEvent, "FrameGenerationGetBeforeHudEvent");
				Bind<EventGetter>(out FrameGenerationGetAfterHudEvent, "FrameGenerationGetAfterHudEvent");
				Bind<MarkerAction>(out FrameGenerationMarker, "FrameGenerationMarker");
				Bind<IntSetter>(out ReflexSetFrameLimit, "ReflexSetFrameLimit");
				Bind<IntQuery>(out ReflexFrameLimit, "ReflexFrameLimit");
				Bind<IntQuery>(out ReflexGuardWaits, "ReflexGuardWaits");
				Bind<IntSetter>(out FramePacerWait, "FramePacerWait");
				Bind<DiagnosticsCreateDelegate>(out DiagnosticsCreate, "DiagnosticsCreate");
				Bind<EventGetter>(out DiagnosticsGetEvent, "DiagnosticsGetEvent");
				Bind<EventGetter>(out DiagnosticsGetFinalCopyEvent, "DiagnosticsGetFinalCopyEvent");
				Bind<ContextQuery>(out DiagnosticsState, "DiagnosticsState");
				Bind<ContextAction>(out DiagnosticsDestroy, "DiagnosticsDestroy");
				Bind<CaptureArmDelegate>(out CaptureArm, "CaptureArm");
				Bind<ContextQuery>(out CaptureState, "CaptureState");
				Bind<ContextAction>(out CaptureCancel, "CaptureCancel");
				Bind<IntAction>(out ProfilerSetEnabled, "ProfilerSetEnabled");
				Bind<StringQuery>(out ProfilerRegister, "ProfilerRegister");
				Bind<StringAction>(out ProfilerSetContext, "ProfilerSetContext");
				Bind<EventGetter>(out ProfilerGetEvent, "ProfilerGetEvent");
			}
		}

		private static void Bind<T>(out T field, string name) where T : Delegate
		{
			IntPtr procAddress = GetProcAddress(module, "RiskOfRainUpscaling_" + name);
			if (procAddress == IntPtr.Zero)
			{
				throw new EntryPointNotFoundException("RiskOfRainUpscaling_" + name);
			}
			field = Marshal.GetDelegateForFunctionPointer<T>(procAddress);
		}
	}
	internal static class PackagePaths
	{
		internal static string FindFile(string root, string name)
		{
			string[] files = Directory.GetFiles(root, name, SearchOption.AllDirectories);
			if (files.Length != 1)
			{
				throw new InvalidOperationException("Expected one " + name + " under " + root + "; found " + files.Length + ". Check for missing or duplicate installations.");
			}
			return files[0];
		}

		internal static string RuntimeFolder(string pluginRoot)
		{
			return Path.Combine(Path.GetDirectoryName(FindFile(pluginRoot, "RiskOfRainUpscaling.dll")), "runtimes");
		}
	}
	internal enum FrameGenerationBackend
	{
		Auto,
		DLSS,
		FSR
	}
	internal sealed class FrameGenerationSetting
	{
		internal const string Section = "Frame Generation";

		internal const string Description = "Off or 2x-6x Frame Generation (DLSS Frame Generation on supported NVIDIA GPUs, FSR Frame Generation elsewhere; see Backend). FSR generates one frame per rendered frame, so 3x-6x run at 2x. Frame generation requires the D3D12 presentation runtime to be active. This means enabling frame generation requires a restart. Turning Off keeps D3D12 for this session; restarting with Off saved starts D3D11. This feature requires upscaling to function. Unsupported multipliers use the highest supported mode.";

		internal readonly ConfigEntry<bool> Requested;

		internal readonly ConfigEntry<int> Multiplier;

		internal readonly ConfigEntry<FrameGenerationBackend> Backend;

		internal readonly bool EnabledAtStartup;

		internal readonly int MultiplierAtStartup;

		internal bool RuntimeAvailable { get; private set; }

		internal bool RestartRequired
		{
			get
			{
				if (Requested.Value)
				{
					return !RuntimeAvailable;
				}
				return false;
			}
		}

		internal bool LiveEnabled
		{
			get
			{
				if (RuntimeAvailable)
				{
					return Requested.Value;
				}
				return false;
			}
		}

		internal int LiveMultiplier
		{
			get
			{
				if (!LiveEnabled)
				{
					return 0;
				}
				return Multiplier.Value;
			}
		}

		internal void SetPresentationState(int state)
		{
			if (state != 1)
			{
				RuntimeAvailable = state == 2;
			}
		}

		internal FrameGenerationSetting(ConfigFile config)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			Requested = config.Bind<bool>("Frame Generation", "Enabled", false, "Off or 2x-6x Frame Generation (DLSS Frame Generation on supported NVIDIA GPUs, FSR Frame Generation elsewhere; see Backend). FSR generates one frame per rendered frame, so 3x-6x run at 2x. Frame generation requires the D3D12 presentation runtime to be active. This means enabling frame generation requires a restart. Turning Off keeps D3D12 for this session; restarting with Off saved starts D3D11. This feature requires upscaling to function. Unsupported multipliers use the highest supported mode.");
			Multiplier = config.Bind<int>("Frame Generation", "Multiplier", 2, new ConfigDescription("Total generated frames per rendered frame when Frame Generation is enabled (2–6). Off/On and multiplier changes apply live once the D3D12 presentation runtime is active. Enabling from Off requires a restart. Unsupported values fall back to the GPU/driver's maximum.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 6), Array.Empty<object>()));
			Backend = config.Bind<FrameGenerationBackend>("Frame Generation", "Backend", FrameGenerationBackend.Auto, "Frame Generation runtime. Auto uses DLSS Frame Generation on supported NVIDIA GPUs and AMD FSR Frame Generation on other GPUs. FSR generates one frame per rendered frame (2x) regardless of multiplier selected. FSR has no Reflex, so the game's FPS cap is used. Requires a restart.");
			EnabledAtStartup = Requested.Value;
			MultiplierAtStartup = Multiplier.Value;
			RuntimeAvailable = EnabledAtStartup;
		}
	}
	internal enum ModLogLevel
	{
		Off,
		Error,
		Warning,
		Info,
		Debug
	}
	internal sealed class LoggingSettings
	{
		internal const string Section = "Diagnostics";

		internal readonly ConfigEntry<ModLogLevel> Level;

		internal LoggingSettings(ConfigFile config)
		{
			Level = config.Bind<ModLogLevel>("Diagnostics", "Logging Level", ModLogLevel.Off, "Controls this mod's BepInEx output, managed.log and native.log. Off stops new messages; Error logs failures; Warning adds warnings; Info adds status; Debug adds detailed traces. Applies live and at startup. NVIDIA SDK log files are separate.");
		}

		internal bool Allows(ModLogLevel severity)
		{
			return Allows(Level.Value, severity);
		}

		internal static bool Allows(ModLogLevel level, ModLogLevel severity)
		{
			if (severity >= ModLogLevel.Error && severity <= ModLogLevel.Debug)
			{
				return level >= severity;
			}
			return false;
		}

		internal void Write(ManualLogSource source, ModLogLevel severity, string message)
		{
			if (Allows(severity))
			{
				source.Log((LogLevel)(severity switch
				{
					ModLogLevel.Debug => 32, 
					ModLogLevel.Warning => 4, 
					ModLogLevel.Error => 2, 
					_ => 16, 
				}), (object)message);
			}
		}
	}
}
namespace RiskOfRainUpscaling.Preloader
{
	public static class Patcher
	{
		public static IEnumerable<string> TargetDLLs => new string[0];

		public static void Patch(AssemblyDefinition assembly)
		{
		}

		public static void Initialize()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ManualLogSource val = Logger.CreateLogSource("RiskOfRainUpscaling.Startup");
			LoggingSettings loggingSettings = null;
			try
			{
				ConfigFile val2 = new ConfigFile(Path.Combine(Paths.ConfigPath, "xanderfrangos.riskofrainupscaling.cfg"), true);
				loggingSettings = new LoggingSettings(val2);
				if (!val2.Bind<bool>("Diagnostics", "TraceGraphicsStartup", true, "Install the early graphics hooks that the D3D12 presentation bridge and Frame Generation require (their startup is also logged to native.log). Disabling this keeps Frame Generation off. Requires restart.").Value)
				{
					loggingSettings.Write(val, ModLogLevel.Warning, "Graphics startup tracing disabled; Frame Generation stays OFF. Enable TraceGraphicsStartup and restart to install early hooks.");
					return;
				}
				string? directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				string runtimes = PackagePaths.RuntimeFolder(Paths.PluginPath);
				FrameGenerationSetting frameGenerationSetting = new FrameGenerationSetting(val2);
				loggingSettings.Write(val, ModLogLevel.Info, "Frame Generation startup=" + (frameGenerationSetting.EnabledAtStartup ? (frameGenerationSetting.MultiplierAtStartup + "x; backend=" + frameGenerationSetting.Backend.Value.ToString() + "; D3D12 presentation") : "Off; D3D11 presentation") + "; Off/on and multipliers apply live in D3D12; enabling from D3D11 requires restart.");
				NativeApi.Load(Path.Combine(directoryName, "RiskOfRainUpscaling.Native.dll"));
				NativeApi.SetLoggingLevel((int)loggingSettings.Level.Value);
				int num = NativeApi.Initialize(Path.Combine(Paths.BepInExRootPath, "RiskOfRainUpscaling-Diagnostics"), runtimes, "preloader");
				if (num <= 0)
				{
					loggingSettings.Write(val, ModLogLevel.Warning, "No new early graphics hooks installed; Frame Generation requires observed device and swap-chain creation. See RiskOfRainUpscaling-Diagnostics/native.log.");
				}
				else
				{
					loggingSettings.Write(val, ModLogLevel.Info, "Startup observer installed; patched import slots=" + num + ". See RiskOfRainUpscaling-Diagnostics/native.log.");
				}
			}
			catch (Exception ex)
			{
				string text = "Startup observer unavailable; Frame Generation stays OFF and the original renderer continues. " + ex;
				if (loggingSettings == null)
				{
					val.LogError((object)text);
				}
				else
				{
					loggingSettings.Write(val, ModLogLevel.Error, text);
				}
			}
		}
	}
}

BepInEx/plugins/RiskOfRainUpscaling/RiskOfRainUpscaling.dll

Decompiled 18 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RiskOfOptions.Utils;
using RoR2;
using RoR2.ConVar;
using RoR2.PostProcess;
using RoR2.UI;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.LowLevel;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Xander Frangos")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("RiskOfRainUpscaling")]
[assembly: AssemblyTitle("RiskOfRainUpscaling")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RiskOfRainUpscaling
{
	internal sealed class ModLog : IDisposable
	{
		private readonly Func<ModLogLevel, bool> allows;

		private readonly Action<ModLogLevel, string> sink;

		private readonly object fileLock = new object();

		private StreamWriter file;

		internal ModLog(Func<ModLogLevel, bool> allows, Action<ModLogLevel, string> sink, string path = null)
		{
			this.allows = allows;
			this.sink = sink;
			if (path == null)
			{
				return;
			}
			try
			{
				file = new StreamWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
				{
					AutoFlush = true
				};
			}
			catch (Exception ex)
			{
				sink?.Invoke(ModLogLevel.Warning, "Log file unavailable (" + path + "): " + ex.Message);
			}
		}

		internal static ModLog To(Action<string> sink)
		{
			return new ModLog((ModLogLevel _) => true, delegate(ModLogLevel _, string message)
			{
				sink(message);
			});
		}

		internal bool IsEnabled(ModLogLevel level)
		{
			return allows(level);
		}

		internal void Write(ModLogLevel level, string message)
		{
			if (!allows(level))
			{
				return;
			}
			sink?.Invoke(level, message);
			lock (fileLock)
			{
				if (file == null)
				{
					return;
				}
				try
				{
					file.WriteLine(DateTime.UtcNow.ToString("O") + " " + level.ToString().ToUpperInvariant() + " " + message);
				}
				catch (Exception)
				{
					file.Dispose();
					file = null;
				}
			}
		}

		internal void Error(string message)
		{
			Write(ModLogLevel.Error, message);
		}

		internal void Warning(string message)
		{
			Write(ModLogLevel.Warning, message);
		}

		internal void Info(string message)
		{
			Write(ModLogLevel.Info, message);
		}

		internal void Debug(string message)
		{
			Write(ModLogLevel.Debug, message);
		}

		internal void Debug(Func<string> message)
		{
			if (allows(ModLogLevel.Debug))
			{
				Write(ModLogLevel.Debug, message());
			}
		}

		public void Dispose()
		{
			lock (fileLock)
			{
				file?.Dispose();
				file = null;
			}
		}
	}
	internal sealed class PipelineResources
	{
		internal static readonly List<PipelineResources> RetainedOnExit = new List<PipelineResources>();

		internal UpscalerSession Session;

		internal Camera Scene;

		internal Camera Hud;

		internal Camera Sky;

		internal SceneTail Tail;

		internal RenderTexture World;

		internal RenderTexture Color;

		internal RenderTexture Depth;

		internal RenderTexture Motion;

		internal RenderTexture HudFree;

		internal RenderTexture DepthView;

		internal RenderTexture MotionView;

		internal RenderTexture Final;

		internal RenderTexture[] Frozen;

		internal int RequestFrame;

		internal RenderPipeline.CaptureMetadata CapturedScene;

		internal CommandBuffer Geometry;

		internal CommandBuffer Before;

		internal CommandBuffer After;

		internal CommandBuffer Presentation;

		internal CommandBuffer FgBefore;

		internal CommandBuffer FgAfter;

		internal CommandBuffer UpscalePre;

		internal CommandBuffer DiagnosticPreviews;

		internal CommandBuffer DiagnosticFinal;

		internal IntPtr Context;

		internal IntPtr Diagnostics;

		internal bool DiagnosticsFailureReported;

		internal bool diagnosticsUnavailable;

		internal int Width;

		internal int Height;

		internal int InputWidth;

		internal int InputHeight;

		internal bool Low;

		internal bool SkyActive;

		internal float Near;

		internal float Far;

		internal float SceneOrder;

		internal float HudOrder;

		internal readonly HashSet<string> OrderStates = new HashSet<string>();

		private readonly List<RenderTexture> textures = new List<RenderTexture>();

		private CameraClearFlags sceneClear;

		private CameraClearFlags skyClear;

		private Color sceneBackground;

		private Color skyBackground;

		private bool changedSceneClear;

		private bool changedSkyClear;

		private readonly Dictionary<CameraResolutionScaler, bool> scalers = new Dictionary<CameraResolutionScaler, bool>();

		internal bool DiagnosticsReady
		{
			get
			{
				if (Diagnostics != IntPtr.Zero)
				{
					return NativeApi.DiagnosticsState(Diagnostics) >= 0;
				}
				return false;
			}
		}

		internal void EnsureDiagnostics(Action<string> log)
		{
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			if (Diagnostics != IntPtr.Zero || diagnosticsUnavailable)
			{
				return;
			}
			try
			{
				DepthView = (Object.op_Implicit((Object)(object)DepthView) ? DepthView : Texture("DepthPreview", InputWidth, InputHeight, (RenderTextureFormat)0));
				MotionView = (Object.op_Implicit((Object)(object)MotionView) ? MotionView : Texture("MotionPreview", InputWidth, InputHeight, (RenderTextureFormat)0));
				Final = (Object.op_Implicit((Object)(object)Final) ? Final : Texture("Final", Width, Height, (RenderTextureFormat)0));
				NativeApi.DiagnosticsDescription description = new NativeApi.DiagnosticsDescription
				{
					Size = (uint)Marshal.SizeOf<NativeApi.DiagnosticsDescription>(),
					Version = 1u,
					InputWidth = InputWidth,
					InputHeight = InputHeight,
					OutputWidth = Width,
					OutputHeight = Height,
					Near = Near,
					Far = Far,
					DepthRange = 200f,
					MotionGain = 20f,
					ReversedDepth = (SystemInfo.usesReversedZBuffer ? 1 : 0),
					Depth = ((Texture)Depth).GetNativeTexturePtr(),
					Motion = ((Texture)Motion).GetNativeTexturePtr(),
					DepthPreview = ((Texture)DepthView).GetNativeTexturePtr(),
					MotionPreview = ((Texture)MotionView).GetNativeTexturePtr(),
					FinalColor = ((Texture)Final).GetNativeTexturePtr(),
					SceneColor = ((Texture)Color).GetNativeTexturePtr(),
					SceneBeforeHud = ((Texture)HudFree).GetNativeTexturePtr()
				};
				Diagnostics = NativeApi.DiagnosticsCreate(ref description);
				if (Diagnostics == IntPtr.Zero)
				{
					throw new InvalidOperationException("native diagnostics context unavailable");
				}
			}
			catch (Exception ex)
			{
				diagnosticsUnavailable = true;
				log("DIAGNOSTICS_UNAVAILABLE " + ex.Message + "; overlay previews and capture are off for this camera.");
				return;
			}
			DiagnosticPreviews = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.Diagnostics.Previews"
			};
			Scene.AddCommandBuffer((CameraEvent)17, DiagnosticPreviews);
			DiagnosticFinal = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.Diagnostics.FinalCopy"
			};
			Hud.AddCommandBuffer((CameraEvent)20, DiagnosticFinal);
		}

		internal void RecordDiagnostics(bool wanted)
		{
			if (DiagnosticPreviews != null)
			{
				DiagnosticPreviews.Clear();
				DiagnosticFinal.Clear();
				if (wanted && DiagnosticsReady)
				{
					DiagnosticPreviews.IssuePluginEventAndData(NativeApi.DiagnosticsGetEvent(), 1, Diagnostics);
					DiagnosticFinal.IssuePluginEventAndData(NativeApi.DiagnosticsGetFinalCopyEvent(), Time.frameCount, Diagnostics);
				}
			}
		}

		internal void PrepareCapture(int frame)
		{
			ReleaseCapture();
			RenderTexture[] source = (RenderTexture[])(object)new RenderTexture[7] { Color, HudFree, Depth, Motion, DepthView, MotionView, Final };
			Frozen = source.Select((RenderTexture val) => Texture("Frozen." + ((Object)val).name, ((Texture)val).width, ((Texture)val).height, val.format, 0, owned: false)).ToArray();
			RequestFrame = frame;
			CapturedScene = null;
			NativeApi.CaptureDescription description = new NativeApi.CaptureDescription
			{
				Size = (uint)Marshal.SizeOf<NativeApi.CaptureDescription>(),
				Version = 1u,
				UnityFrame = frame,
				SceneColor = ((Texture)Frozen[0]).GetNativeTexturePtr(),
				SceneBeforeHud = ((Texture)Frozen[1]).GetNativeTexturePtr(),
				Depth = ((Texture)Frozen[2]).GetNativeTexturePtr(),
				Motion = ((Texture)Frozen[3]).GetNativeTexturePtr(),
				DepthPreview = ((Texture)Frozen[4]).GetNativeTexturePtr(),
				MotionPreview = ((Texture)Frozen[5]).GetNativeTexturePtr(),
				FinalColor = ((Texture)Frozen[6]).GetNativeTexturePtr()
			};
			if (NativeApi.CaptureArm(Diagnostics, ref description) != 0)
			{
				throw new InvalidOperationException("Native capture arm rejected");
			}
		}

		internal void ReleaseCapture()
		{
			if (Frozen == null)
			{
				return;
			}
			RenderTexture[] frozen = Frozen;
			foreach (RenderTexture val in frozen)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.Release();
					Object.Destroy((Object)(object)val);
				}
			}
			Frozen = null;
		}

		internal PipelineResources(CameraRigController rig, int width, int height, int inputWidth, int inputHeight, bool low)
		{
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			Scene = rig.sceneCam;
			Hud = rig.uiCam;
			Sky = rig.skyboxCam;
			Width = width;
			Height = height;
			InputWidth = inputWidth;
			InputHeight = inputHeight;
			Low = low;
			Near = Scene.nearClipPlane;
			Far = Scene.farClipPlane;
			SkyActive = Object.op_Implicit((Object)(object)Sky) && ((Behaviour)Sky).isActiveAndEnabled;
			SceneOrder = Scene.depth;
			HudOrder = Hud.depth;
			try
			{
				Color = Texture("SceneInput", inputWidth, inputHeight, (RenderTextureFormat)2);
				Depth = Texture("RawDepth", inputWidth, inputHeight, (RenderTextureFormat)14);
				Motion = Texture("RawMotion", inputWidth, inputHeight, (RenderTextureFormat)13);
				HudFree = Texture("HudFree", width, height, (RenderTextureFormat)2);
				if (low)
				{
					World = Texture("LowResolutionWorld", inputWidth, inputHeight, (RenderTextureFormat)2, 24);
				}
				NativeApi.SceneInputsDescription description = new NativeApi.SceneInputsDescription
				{
					Size = (uint)Marshal.SizeOf<NativeApi.SceneInputsDescription>(),
					Version = 4u,
					Width = inputWidth,
					Height = inputHeight,
					Depth = ((Texture)Depth).GetNativeTexturePtr()
				};
				Context = NativeApi.SceneInputsCreate(ref description);
				if (Context == IntPtr.Zero)
				{
					throw new InvalidOperationException("Native scene inputs context unavailable");
				}
			}
			catch
			{
				if (Context != IntPtr.Zero)
				{
					CommandBuffer val = new CommandBuffer();
					try
					{
						val.IssuePluginEventAndData(NativeApi.SceneInputsGetEvent(), 199, Context);
						Graphics.ExecuteCommandBuffer(val);
					}
					finally
					{
						val.Release();
					}
					RetainedOnExit.Add(this);
				}
				else
				{
					Release();
				}
				throw;
			}
		}

		private RenderTexture Texture(string name, int width, int height, RenderTextureFormat format, int depth = 0, bool owned = true)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture val = new RenderTexture(width, height, depth, format, (RenderTextureReadWrite)1)
			{
				name = "RiskOfRainUpscaling.Pipeline." + name,
				filterMode = (FilterMode)1,
				antiAliasing = 1,
				useMipMap = false,
				autoGenerateMips = false
			};
			if (owned)
			{
				textures.Add(val);
			}
			if (!val.Create())
			{
				if (!owned)
				{
					Object.Destroy((Object)(object)val);
				}
				throw new InvalidOperationException("Texture creation failed: " + name);
			}
			RenderTexture active = RenderTexture.active;
			try
			{
				RenderTexture.active = val;
				GL.Clear(true, true, Color.clear);
				return val;
			}
			finally
			{
				RenderTexture.active = active;
			}
		}

		internal void Route()
		{
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Invalid comparison between Unknown and I4
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Invalid comparison between Unknown and I4
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Invalid comparison between Unknown and I4
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Invalid comparison between Unknown and I4
			foreach (Camera item in ((IEnumerable<Camera>)(object)new Camera[2] { Scene, Sky }).Where((Camera c) => Object.op_Implicit((Object)(object)c) && ((Behaviour)c).isActiveAndEnabled))
			{
				CameraResolutionScaler[] components = ((Component)item).GetComponents<CameraResolutionScaler>();
				foreach (CameraResolutionScaler val in components)
				{
					scalers[val] = ((Behaviour)val).enabled;
					((Behaviour)val).enabled = false;
				}
			}
			Scene.targetTexture = World;
			DisplaySpace.Route(Scene, InputWidth, InputHeight, Width, Height);
			Tail = ((Component)Scene).gameObject.AddComponent<SceneTail>();
			if (Object.op_Implicit((Object)(object)Sky) && ((Behaviour)Sky).isActiveAndEnabled)
			{
				Sky.targetTexture = World;
				skyClear = Sky.clearFlags;
				skyBackground = Sky.backgroundColor;
				if ((int)Sky.clearFlags == 3 || (int)Sky.clearFlags == 4)
				{
					Sky.clearFlags = (CameraClearFlags)2;
					Sky.backgroundColor = Color.black;
					changedSkyClear = true;
				}
			}
			else if ((int)Scene.clearFlags == 3 || (int)Scene.clearFlags == 4)
			{
				sceneClear = Scene.clearFlags;
				sceneBackground = Scene.backgroundColor;
				Scene.clearFlags = (CameraClearFlags)2;
				Scene.backgroundColor = Color.black;
				changedSceneClear = true;
			}
			Presentation = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.Routing.WorldIntoHudTarget"
			};
			Profiling.Begin(Presentation, "route.blit upscaled world -> HUD target");
			Presentation.Blit((Texture)(object)HudFree, RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2));
			Profiling.End(Presentation, "route.blit upscaled world -> HUD target");
			Presentation.SetRenderTarget(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2));
			Hud.AddCommandBuffer((CameraEvent)10, Presentation);
		}

		internal bool TailIsLast()
		{
			if (Object.op_Implicit((Object)(object)Tail))
			{
				return (Object)(object)(from component in ((Component)Scene).GetComponents<MonoBehaviour>()
					where Object.op_Implicit((Object)(object)component) && ((Behaviour)component).isActiveAndEnabled && ((object)component).GetType().GetMethod("OnRenderImage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null
					select component).LastOrDefault() == (Object)(object)Tail;
			}
			return false;
		}

		internal void Restore()
		{
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Invalid comparison between Unknown and I4
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Invalid comparison between Unknown and I4
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			Session?.Restore();
			foreach (KeyValuePair<CameraResolutionScaler, bool> scaler in scalers)
			{
				if (Object.op_Implicit((Object)(object)scaler.Key) && !((Behaviour)scaler.Key).enabled)
				{
					((Behaviour)scaler.Key).enabled = scaler.Value;
				}
			}
			scalers.Clear();
			if (Object.op_Implicit((Object)(object)Scene))
			{
				if (Geometry != null)
				{
					Scene.RemoveCommandBuffer((CameraEvent)5, Geometry);
				}
				if (Before != null)
				{
					Scene.RemoveCommandBuffer((CameraEvent)17, Before);
				}
				if (UpscalePre != null)
				{
					Scene.RemoveCommandBuffer((CameraEvent)17, UpscalePre);
				}
				if (After != null)
				{
					Scene.RemoveCommandBuffer((CameraEvent)20, After);
				}
				DisplaySpace.Clear(Scene);
				if (Object.op_Implicit((Object)(object)World) && (Object)(object)Scene.targetTexture == (Object)(object)World)
				{
					Scene.targetTexture = null;
				}
				if (changedSceneClear && (int)Scene.clearFlags == 2)
				{
					Scene.clearFlags = sceneClear;
					Scene.backgroundColor = sceneBackground;
				}
			}
			if (Object.op_Implicit((Object)(object)Sky))
			{
				if (Object.op_Implicit((Object)(object)World) && (Object)(object)Sky.targetTexture == (Object)(object)World)
				{
					Sky.targetTexture = null;
				}
				if (changedSkyClear && (int)Sky.clearFlags == 2)
				{
					Sky.clearFlags = skyClear;
					Sky.backgroundColor = skyBackground;
				}
			}
			if (Object.op_Implicit((Object)(object)Scene) && DiagnosticPreviews != null)
			{
				Scene.RemoveCommandBuffer((CameraEvent)17, DiagnosticPreviews);
			}
			if (Object.op_Implicit((Object)(object)Hud) && DiagnosticFinal != null)
			{
				Hud.RemoveCommandBuffer((CameraEvent)20, DiagnosticFinal);
			}
			if (Object.op_Implicit((Object)(object)Hud) && Presentation != null)
			{
				Hud.RemoveCommandBuffer((CameraEvent)10, Presentation);
			}
			if (Object.op_Implicit((Object)(object)Hud) && FgBefore != null)
			{
				Hud.RemoveCommandBuffer((CameraEvent)10, FgBefore);
			}
			if (Object.op_Implicit((Object)(object)Hud) && FgAfter != null)
			{
				Hud.RemoveCommandBuffer((CameraEvent)18, FgAfter);
			}
			if (Object.op_Implicit((Object)(object)Tail))
			{
				Tail.Process = null;
				((Behaviour)Tail).enabled = false;
				Object.Destroy((Object)(object)Tail);
				Tail = null;
			}
			CommandBuffer geometry = Geometry;
			if (geometry != null)
			{
				geometry.Release();
			}
			CommandBuffer before = Before;
			if (before != null)
			{
				before.Release();
			}
			CommandBuffer after = After;
			if (after != null)
			{
				after.Release();
			}
			CommandBuffer presentation = Presentation;
			if (presentation != null)
			{
				presentation.Release();
			}
			Geometry = (Before = (After = (Presentation = null)));
			CommandBuffer diagnosticPreviews = DiagnosticPreviews;
			if (diagnosticPreviews != null)
			{
				diagnosticPreviews.Release();
			}
			CommandBuffer diagnosticFinal = DiagnosticFinal;
			if (diagnosticFinal != null)
			{
				diagnosticFinal.Release();
			}
			DiagnosticPreviews = (DiagnosticFinal = null);
			CommandBuffer fgBefore = FgBefore;
			if (fgBefore != null)
			{
				fgBefore.Release();
			}
			FgBefore = null;
			CommandBuffer fgAfter = FgAfter;
			if (fgAfter != null)
			{
				fgAfter.Release();
			}
			FgAfter = null;
			CommandBuffer upscalePre = UpscalePre;
			if (upscalePre != null)
			{
				upscalePre.Release();
			}
			UpscalePre = null;
		}

		internal void Release()
		{
			Session?.Release();
			ReleaseCapture();
			foreach (RenderTexture texture in textures)
			{
				if (Object.op_Implicit((Object)(object)texture))
				{
					texture.Release();
					Object.Destroy((Object)(object)texture);
				}
			}
			textures.Clear();
		}
	}
	[BepInPlugin("xanderfrangos.riskofrainupscaling", "Risk of Rain Upscaling", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private readonly Dictionary<int, string> cameraStates = new Dictionary<int, string>();

		private float nextScan;

		private string lastBuild;

		internal const string Guid = "xanderfrangos.riskofrainupscaling";

		private ModSettings settings;

		private ModLog log;

		private volatile bool loggingPending = true;

		internal Func<bool> IsBindingHotkey = () => false;

		private bool sharpnessPending = true;

		private volatile bool frameGenerationMultiplierPending = true;

		private volatile bool frameGenerationRestartPrompt;

		private string logFolder;

		private bool nativeLoaded;

		private RenderPipeline pipeline;

		internal const string Version = "1.0.1";

		private void WriteEnvironment()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Write("Risk of Rain Upscaling 1.0.1; hotkeys enabled=" + settings.HotkeysEnabled.Value + "; toggle upscaling=" + ((object)settings.ToggleReconstruction.Value/*cast due to .constrained prefix*/).ToString() + "; toggle Frame Generation=" + ((object)settings.ToggleFrameGeneration.Value/*cast due to .constrained prefix*/).ToString());
			Write("Unity=" + Application.unityVersion + "; game=" + Application.version + "; BepInEx=" + typeof(BaseUnityPlugin).Assembly.GetName().Version?.ToString() + "; CLR=" + Environment.Version?.ToString() + "; runtime=" + ((Type.GetType("Mono.Runtime") != null) ? "Mono" : "other"));
			Write("API=" + ((object)SystemInfo.graphicsDeviceType/*cast due to .constrained prefix*/).ToString() + "; GPU=" + SystemInfo.graphicsDeviceName + "; driver/API=" + SystemInfo.graphicsDeviceVersion + "; vendor=" + SystemInfo.graphicsDeviceVendor + "; memoryMiB=" + SystemInfo.graphicsMemorySize + "; OS=" + SystemInfo.operatingSystem);
			Write("Profile=" + Paths.BepInExRootPath + "; executable=" + Paths.ExecutablePath + "; resolution=" + Screen.width + "x" + Screen.height);
			Write("Pipeline=" + PipelineName());
		}

		private void TickReport()
		{
			if (Time.unscaledTime >= nextScan)
			{
				nextScan = Time.unscaledTime + 2f;
				if (log.IsEnabled(ModLogLevel.Debug))
				{
					ScanCameras();
				}
				string buildId = RoR2Application.GetBuildId();
				if (buildId != lastBuild)
				{
					lastBuild = buildId;
					Write("RoR2 build=" + buildId);
				}
			}
		}

		private static string PipelineName()
		{
			RenderPipelineAsset currentRenderPipeline = GraphicsSettings.currentRenderPipeline;
			if (!Object.op_Implicit((Object)(object)currentRenderPipeline))
			{
				return "Built-in (no active render-pipeline asset)";
			}
			return ((object)currentRenderPipeline).GetType().FullName;
		}

		private void ScanCameras()
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			HashSet<int> live = new HashSet<int>();
			Camera[] allCameras = Camera.allCameras;
			foreach (Camera camera in allCameras)
			{
				int instanceID = ((Object)camera).GetInstanceID();
				live.Add(instanceID);
				CameraRigController val = ((IEnumerable<CameraRigController>)CameraRigController.readOnlyInstancesList).FirstOrDefault((Func<CameraRigController, bool>)((CameraRigController r) => Object.op_Implicit((Object)(object)r) && ((Object)(object)r.sceneCam == (Object)(object)camera || (Object)(object)r.uiCam == (Object)(object)camera || (Object)(object)r.skyboxCam == (Object)(object)camera)));
				string text = ((!Object.op_Implicit((Object)(object)val)) ? "unowned/preview/reflection" : (((Object)(object)val.uiCam == (Object)(object)camera) ? "HUD" : (((Object)(object)val.skyboxCam == (Object)(object)camera) ? "skybox" : (CameraRole(camera, menus: true) ?? "scene/spectator/cutscene/split-viewport"))));
				string text2 = string.Join(",", from c in ((Component)camera).GetComponents<Component>()
					where Object.op_Implicit((Object)(object)c) && (((object)c).GetType().FullName.IndexOf("PostProcess", StringComparison.OrdinalIgnoreCase) >= 0 || ((object)c).GetType().FullName.IndexOf("Render", StringComparison.OrdinalIgnoreCase) >= 0)
					select ((object)c).GetType().FullName);
				string[] obj = new string[28]
				{
					"Camera id=",
					instanceID.ToString(),
					"; name=",
					((Object)camera).name,
					"; scene=",
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null,
					null
				};
				Scene scene = ((Component)camera).gameObject.scene;
				obj[5] = ((Scene)(ref scene)).name;
				obj[6] = "; role=";
				obj[7] = text;
				obj[8] = "; type=";
				obj[9] = ((object)camera.cameraType/*cast due to .constrained prefix*/).ToString();
				obj[10] = "; path=";
				obj[11] = ((object)camera.actualRenderingPath/*cast due to .constrained prefix*/).ToString();
				obj[12] = "; size=";
				obj[13] = camera.pixelWidth.ToString();
				obj[14] = "x";
				obj[15] = camera.pixelHeight.ToString();
				obj[16] = "; viewport=";
				obj[17] = ((object)camera.rect/*cast due to .constrained prefix*/).ToString();
				obj[18] = "; depth=";
				obj[19] = camera.depth.ToString();
				obj[20] = "; cullingMask=";
				obj[21] = camera.cullingMask.ToString();
				obj[22] = "; target=";
				obj[23] = (Object.op_Implicit((Object)(object)camera.targetTexture) ? ((Object)camera.targetTexture).name : "display");
				obj[24] = "; depthMode=";
				obj[25] = ((object)camera.depthTextureMode/*cast due to .constrained prefix*/).ToString();
				obj[26] = "; post/render=";
				obj[27] = text2;
				string text3 = string.Concat(obj);
				if (!cameraStates.TryGetValue(instanceID, out var value) || value != text3)
				{
					Write(text3, ModLogLevel.Debug);
					cameraStates[instanceID] = text3;
				}
			}
			int[] array = cameraStates.Keys.Where((int id) => !live.Contains(id)).ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				int key = array[i];
				Write("Camera removed id=" + key, ModLogLevel.Debug);
				cameraStates.Remove(key);
			}
		}

		private void Write(string message, ModLogLevel severity = ModLogLevel.Info)
		{
			log.Write(severity, message);
		}

		private void Awake()
		{
			settings = new ModSettings(((BaseUnityPlugin)this).Config);
			settings.Generation.SetPresentationState(0);
			settings.Sharpness.SettingChanged += SharpnessChanged;
			settings.Generation.Multiplier.SettingChanged += FrameGenerationMultiplierChanged;
			settings.Generation.Requested.SettingChanged += FrameGenerationEnabledChanged;
			settings.LoggingLevel.SettingChanged += LoggingChanged;
			logFolder = Path.Combine(Paths.BepInExRootPath, "RiskOfRainUpscaling-Diagnostics");
			Directory.CreateDirectory(logFolder);
			log = new ModLog(settings.Logging.Allows, delegate(ModLogLevel level, string message)
			{
				settings.Logging.Write(((BaseUnityPlugin)this).Logger, level, message);
			}, Path.Combine(logFolder, "managed.log"));
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				try
				{
					GameFrameRateSetting frameRate = new GameFrameRateSetting(delegate
					{
						Console instance = Console.instance;
						object obj;
						if (instance == null)
						{
							obj = null;
						}
						else
						{
							BaseConVar obj2 = instance.FindConVar("fps_max");
							obj = ((obj2 != null) ? obj2.GetString() : null);
						}
						if (obj == null)
						{
							obj = Application.targetFrameRate.ToString(CultureInfo.InvariantCulture);
						}
						return (string)obj;
					}, delegate(string value)
					{
						Console.instance.FindConVar("fps_max").SetString(value);
					});
					RiskOfOptionsIntegration.Register(settings, frameRate, () => Resolved() == UpscalerBackend.FSR, () => settings.Upscaling.Value && Resolved() == UpscalerBackend.DLSS, delegate(string message)
					{
						LogMessage(ModLogLevel.Warning, message);
					});
					IsBindingHotkey = RiskOfOptionsIntegration.IsBindingHotkey;
				}
				catch (Exception ex)
				{
					LogMessage(ModLogLevel.Warning, "Risk of Options registration failed: " + ex.Message);
				}
			}
			if (!settings.Enabled.Value)
			{
				LogMessage(ModLogLevel.Info, "Mod disabled by General.Enabled.");
				return;
			}
			WriteEnvironment();
			try
			{
				NativeApi.Load(PackagePaths.FindFile(Paths.PatcherPluginPath, "RiskOfRainUpscaling.Native.dll"));
				NativeApi.SetLoggingLevel((int)settings.LoggingLevel.Value);
				if (NativeApi.Initialize(logFolder, Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "runtimes"), "plugin-awake") < 0)
				{
					LogMessage(ModLogLevel.Warning, "Early graphics hooks missed; Frame Generation stays OFF until restart. Check the preloader installation and TraceGraphicsStartup setting. See native.log.");
				}
				nativeLoaded = true;
				settings.Generation.SetPresentationState(NativeApi.GetPresentationState());
				Write("Presentation=" + NativeApi.PresentationLabel + "; Frame Generation=" + NativeApi.FrameGenerationLabel + "; startup runtime selection in " + ((BaseUnityPlugin)this).Config.ConfigFilePath);
				Write("Native library ready; observed D3D11 devices=" + NativeApi.GetObservedDeviceCount() + " (0 means the preloader hooks missed startup).");
			}
			catch (Exception ex2)
			{
				Write("Native library unavailable: " + ex2.Message, ModLogLevel.Error);
			}
			pipeline = new RenderPipeline(this, settings, log, logFolder, nativeLoaded);
			if (log.IsEnabled(ModLogLevel.Debug))
			{
				ScanCameras();
			}
			UpscalerBackend Resolved()
			{
				return pipeline?.ResolvedUpscaler ?? DlssPolicy.Resolve(settings.Upscaler.Value, 0, SystemInfo.graphicsDeviceVendorID == 4318);
			}
		}

		private void Update()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			ApplyLiveSettings();
			if (frameGenerationRestartPrompt && RoR2Application.loadFinished && Application.isFocused)
			{
				frameGenerationRestartPrompt = false;
				if (settings.Generation.RestartRequired)
				{
					SimpleDialogBox obj = SimpleDialogBox.Create((MPEventSystem)null);
					obj.headerToken = new TokenParamsPair
					{
						token = "Restart required",
						formatParams = Array.Empty<object>()
					};
					obj.descriptionToken = new TokenParamsPair
					{
						token = "Frame Generation is saved as enabled. Restart Risk of Rain 2 to start the required D3D12 presentation runtime.",
						formatParams = Array.Empty<object>()
					};
					obj.AddCancelButton("OK", Array.Empty<object>());
				}
			}
			pipeline?.Tick(settings.Enabled.Value);
			if (settings.Enabled.Value)
			{
				TickReport();
			}
		}

		internal bool Gameplay(Camera camera)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Invalid comparison between Unknown and I4
			foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((Object)(object)readOnlyInstances.sceneCam != (Object)(object)camera))
				{
					LocalUser localUserViewer = readOnlyInstances.localUserViewer;
					bool ownLiveBody = localUserViewer != null && Object.op_Implicit((Object)(object)localUserViewer.cachedBody) && Object.op_Implicit((Object)(object)localUserViewer.cachedBody.healthComponent) && localUserViewer.cachedBody.healthComponent.alive && (Object)(object)localUserViewer.cachedBody == (Object)(object)readOnlyInstances.targetBody;
					Rect rect = camera.rect;
					return CameraPolicy.IsGameplay(sceneCamera: true, localUserViewer != null, ownLiveBody, readOnlyInstances.isCutscene, Object.op_Implicit((Object)(object)camera.targetTexture) && !(pipeline?.OwnsTarget(camera) ?? false), Mathf.Approximately(((Rect)(ref rect)).x, 0f) && Mathf.Approximately(((Rect)(ref rect)).y, 0f) && Mathf.Approximately(((Rect)(ref rect)).width, 1f) && Mathf.Approximately(((Rect)(ref rect)).height, 1f), ((Behaviour)camera).isActiveAndEnabled, (int)camera.cameraType == 1);
				}
			}
			return false;
		}

		internal bool ReconstructionCamera(Camera camera, bool menus)
		{
			return CameraRole(camera, menus) != null;
		}

		internal string CameraRole(Camera camera, bool menus)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Invalid comparison between Unknown and I4
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)camera))
			{
				return null;
			}
			if (Gameplay(camera))
			{
				return "local-gameplay";
			}
			Rect rect = camera.rect;
			Scene scene = ((Component)camera).gameObject.scene;
			bool sceneCamera = CameraRigController.readOnlyInstancesList.Any((CameraRigController r) => Object.op_Implicit((Object)(object)r) && (Object)(object)r.sceneCam == (Object)(object)camera);
			bool runActive = Object.op_Implicit((Object)(object)Run.instance);
			bool renderTexture = Object.op_Implicit((Object)(object)camera.targetTexture) && !(pipeline?.OwnsTarget(camera) ?? false);
			bool fullViewport = Mathf.Approximately(((Rect)(ref rect)).x, 0f) && Mathf.Approximately(((Rect)(ref rect)).y, 0f) && Mathf.Approximately(((Rect)(ref rect)).width, 1f) && Mathf.Approximately(((Rect)(ref rect)).height, 1f);
			bool isActiveAndEnabled = ((Behaviour)camera).isActiveAndEnabled;
			bool gameCamera = (int)camera.cameraType == 1;
			MainMenuController instance = MainMenuController.instance;
			if (CameraPolicy.IsMainMenu(sceneCamera, menus, ((Scene)(ref scene)).name == "title", Object.op_Implicit((Object)(object)instance) && ((Behaviour)instance).isActiveAndEnabled && ((Component)instance).gameObject.scene == scene, runActive, renderTexture, fullViewport, isActiveAndEnabled, gameCamera))
			{
				return "main-menu-scene";
			}
			PreGameController instance2 = PreGameController.instance;
			if (CameraPolicy.IsCharacterSelect(sceneCamera, menus, Object.op_Implicit((Object)(object)instance2) && ((Behaviour)instance2).isActiveAndEnabled && ((Component)instance2).gameObject.scene == scene, runActive, renderTexture, fullViewport, isActiveAndEnabled, gameCamera))
			{
				return "character-select-scene";
			}
			return null;
		}

		internal void LogMessage(ModLogLevel severity, string message)
		{
			log.Write(severity, message);
		}

		private void OnDestroy()
		{
			if (settings != null)
			{
				settings.Sharpness.SettingChanged -= SharpnessChanged;
				settings.Generation.Multiplier.SettingChanged -= FrameGenerationMultiplierChanged;
				settings.Generation.Requested.SettingChanged -= FrameGenerationEnabledChanged;
				settings.LoggingLevel.SettingChanged -= LoggingChanged;
			}
			pipeline?.Dispose();
			log?.Dispose();
		}

		private void OnGUI()
		{
			pipeline?.DrawOverlay();
		}

		internal void RunCapture(IEnumerator routine)
		{
			((MonoBehaviour)this).StartCoroutine(routine);
		}

		internal void PromptFrameGenerationRestart()
		{
			frameGenerationRestartPrompt = true;
		}

		private void SharpnessChanged(object sender, EventArgs args)
		{
			sharpnessPending = true;
		}

		private void LoggingChanged(object sender, EventArgs args)
		{
			loggingPending = true;
		}

		private void FrameGenerationMultiplierChanged(object sender, EventArgs args)
		{
			frameGenerationMultiplierPending = true;
		}

		private void FrameGenerationEnabledChanged(object sender, EventArgs args)
		{
			frameGenerationMultiplierPending = true;
			PromptFrameGenerationRestart();
		}

		private void ApplyLiveSettings()
		{
			if (nativeLoaded)
			{
				if (loggingPending)
				{
					loggingPending = false;
					NativeApi.SetLoggingLevel((int)settings.LoggingLevel.Value);
				}
				bool runtimeAvailable = settings.Generation.RuntimeAvailable;
				settings.Generation.SetPresentationState(NativeApi.GetPresentationState());
				if (runtimeAvailable != settings.Generation.RuntimeAvailable)
				{
					frameGenerationMultiplierPending = true;
				}
			}
			if (nativeLoaded && Profiling.Enabled != (settings.Profiling.Value && settings.Enabled.Value))
			{
				Profiling.Enabled = settings.Profiling.Value && settings.Enabled.Value;
				NativeApi.ProfilerSetEnabled(Profiling.Enabled ? 1 : 0);
				LogMessage(ModLogLevel.Info, "PROFILING " + (Profiling.Enabled ? "on; see profile.log" : "off"));
			}
			if (sharpnessPending && nativeLoaded)
			{
				sharpnessPending = false;
				NativeApi.SetSharpness(settings.Sharpness.Value);
			}
			if (frameGenerationMultiplierPending && nativeLoaded)
			{
				frameGenerationMultiplierPending = false;
				int liveMultiplier = settings.Generation.LiveMultiplier;
				if (liveMultiplier != 0)
				{
					NativeApi.FrameGenerationSetMultiplier(liveMultiplier);
				}
				else
				{
					NativeApi.FrameGenerationSetEnabled(0);
				}
			}
		}
	}
	internal static class Profiling
	{
		private const int BeginKind = 0;

		private const int EndKind = 1;

		private const int InstantKind = 2;

		private static readonly Dictionary<string, int> labels = new Dictionary<string, int>();

		private static CommandBuffer immediate;

		internal static bool Enabled;

		private static bool Available
		{
			get
			{
				if (NativeApi.ProfilerGetEvent != null)
				{
					return NativeApi.ProfilerRegister != null;
				}
				return false;
			}
		}

		private static int Label(string name)
		{
			if (!labels.TryGetValue(name, out var value))
			{
				value = (labels[name] = NativeApi.ProfilerRegister(name));
			}
			return value;
		}

		private static void Issue(CommandBuffer commands, string label, int kind)
		{
			if (Available && commands != null)
			{
				int num = Label(label);
				if (num >= 0)
				{
					commands.IssuePluginEventAndData(NativeApi.ProfilerGetEvent(), (num << 2) | kind, IntPtr.Zero);
				}
			}
		}

		internal static void Begin(CommandBuffer commands, string label)
		{
			Issue(commands, label, 0);
		}

		internal static void End(CommandBuffer commands, string label)
		{
			Issue(commands, label, 1);
		}

		internal static void Mark(CommandBuffer commands, string label)
		{
			Issue(commands, label, 2);
		}

		internal static void BeginNow(string label)
		{
			Now(label, 0);
		}

		internal static void EndNow(string label)
		{
			Now(label, 1);
		}

		private static void Now(string label, int kind)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled && Available)
			{
				immediate = (CommandBuffer)(((object)immediate) ?? ((object)new CommandBuffer
				{
					name = "RiskOfRainUpscaling.Profiler"
				}));
				immediate.Clear();
				Issue(immediate, label, kind);
				Graphics.ExecuteCommandBuffer(immediate);
			}
		}
	}
	internal sealed class ProfilerMarkers
	{
		private readonly List<(Camera camera, CameraEvent stage, CommandBuffer commands)> attached = new List<(Camera, CameraEvent, CommandBuffer)>();

		private Camera scene;

		private Camera sky;

		private Camera hud;

		internal void Update(bool enabled, Camera sceneCamera, Camera skyCamera, Camera hudCamera)
		{
			if (!enabled || !Object.op_Implicit((Object)(object)sceneCamera))
			{
				Remove();
			}
			else if (attached.Count <= 0 || !((Object)(object)scene == (Object)(object)sceneCamera) || !((Object)(object)sky == (Object)(object)skyCamera) || !((Object)(object)hud == (Object)(object)hudCamera) || !attached.All(((Camera camera, CameraEvent stage, CommandBuffer commands) a) => Object.op_Implicit((Object)(object)a.camera)))
			{
				Remove();
				scene = sceneCamera;
				sky = skyCamera;
				hud = hudCamera;
				Attach(sceneCamera, "scene");
				Attach(skyCamera, "sky");
				Attach(hudCamera, "hud");
			}
		}

		private void Attach(Camera camera, string role)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)camera))
			{
				return;
			}
			foreach (CameraEvent value in Enum.GetValues(typeof(CameraEvent)))
			{
				CommandBuffer val2 = new CommandBuffer
				{
					name = "RiskOfRainUpscaling.Profiler." + role + "." + ((object)value/*cast due to .constrained prefix*/).ToString()
				};
				Profiling.Mark(val2, role + ":" + ((object)value/*cast due to .constrained prefix*/).ToString());
				CommandBuffer[] commandBuffers = camera.GetCommandBuffers(value);
				CommandBuffer[] array = commandBuffers;
				foreach (CommandBuffer val3 in array)
				{
					camera.RemoveCommandBuffer(value, val3);
				}
				camera.AddCommandBuffer(value, val2);
				array = commandBuffers;
				foreach (CommandBuffer val4 in array)
				{
					camera.AddCommandBuffer(value, val4);
				}
				attached.Add((camera, value, val2));
			}
		}

		internal void Remove()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			foreach (var (val, val2, val3) in attached)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					val.RemoveCommandBuffer(val2, val3);
				}
				val3.Release();
			}
			attached.Clear();
			scene = (sky = (hud = null));
		}
	}
	internal sealed class RenderPipeline : IDisposable
	{
		[Serializable]
		internal sealed class CaptureMetadata
		{
			public string version = "1.0.1";

			public string utc;

			public string scene;

			public string colorSpace;

			public string presentationMode;

			public string reconstructionMode = "Off";

			public string dlssQuality = "none";

			public string upscaler = "none";

			public string upscalerColorInput = "none";

			public string sceneColorCapturePoint = "scene AfterEverything: end of effect chain before UI";

			public string sceneBeforeHudCapturePoint = "scene AfterEverything";

			public string finalCapturePoint = "HUD camera AfterEverything: before Screen Space - Overlay canvases and IMGUI; rows flipped to Unity orientation";

			public string depthEncoding = "raw hardware depth from same-frame native DSV copy";

			public string motionEncoding = "Unity signed screen UV offsets";

			public string scenePngEncoding;

			public string finalPngEncoding = "srgb";

			public int frame;

			public int inputWidth;

			public int inputHeight;

			public int outputWidth;

			public int outputHeight;

			public int actualCameraWidth;

			public int actualCameraHeight;

			public int scaledCameraWidth;

			public int scaledCameraHeight;

			public int hudWidth;

			public int hudHeight;

			public int upscalerStateAtScene;

			public int depthNonfinite;

			public int motionNonfinite;

			public int motionNonzeroPixels;

			public bool lowerResolution;

			public bool reversedZ;

			public float near;

			public float far;

			public float depthMin;

			public float depthMax;

			public float motionMax;

			public float motionPreviewGain;

			public float depthPreviewRange;

			public Matrix4x4 projection;

			public Matrix4x4 nonJitteredProjection;

			public Matrix4x4 worldToCamera;
		}

		private readonly Plugin plugin;

		private readonly ModSettings settings;

		private readonly string folder;

		private readonly ModLog log;

		private readonly bool available;

		private readonly ConfigEntry<bool> overlay;

		private readonly ConfigEntry<bool> captureWhileOff;

		internal const float MotionPreviewGain = 20f;

		internal const float DepthPreviewRange = 200f;

		private readonly ConfigEntry<bool> upscaling;

		private readonly ConfigEntry<DlssQuality> quality;

		private readonly ConfigEntry<UpscalerBackend> upscaler;

		private readonly ConfigEntry<DlssPreset> preset;

		private readonly ConfigEntry<OutlineMode> outlines;

		private int autoUpscaler;

		private readonly ConfigEntry<float> mipBiasOffset;

		private DlaaPlacement placement;

		private float nextMipScan;

		private float nextMotionScan;

		private readonly List<PipelineResources> retiring = new List<PipelineResources>();

		private PipelineResources active;

		private bool capturing;

		private bool disposed;

		private bool requestedCapture;

		private bool attachFailed;

		private float nextAudit;

		private string lastBlocked;

		private int traceFrames;

		private readonly ConfigEntry<bool> frameGeneration;

		private readonly ConfigEntry<bool> reflexLimiter;

		private readonly ConfigEntry<bool> mainMenu;

		private readonly FrameGenerationSetting generation;

		private bool modEnabled = true;

		private readonly FrameGenerationTiming fgTiming;

		private readonly ProfilerMarkers profilerMarkers = new ProfilerMarkers();

		private string profilerContext;

		internal UpscalerBackend ResolvedUpscaler => DlssPolicy.Resolve(upscaler.Value, autoUpscaler, SystemInfo.graphicsDeviceVendorID == 4318);

		private bool DiagnosticsWanted
		{
			get
			{
				if (!overlay.Value)
				{
					return capturing;
				}
				return true;
			}
		}

		private IEnumerator Capture(PipelineResources resources)
		{
			IEnumerator capture = CaptureCore(resources);
			try
			{
				while (true)
				{
					bool flag;
					try
					{
						flag = capture.MoveNext();
					}
					catch (Exception ex)
					{
						LogError("CAPTURE_FAILED " + ex);
						break;
					}
					if (!flag)
					{
						break;
					}
					yield return capture.Current;
				}
			}
			finally
			{
				IDisposable disposable = capture as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
		}

		private IEnumerator CaptureCore(PipelineResources resources)
		{
			try
			{
				resources.PrepareCapture(Time.frameCount);
				Log("CAPTURE_REQUESTED frame=" + resources.RequestFrame);
				float deadline = Time.realtimeSinceStartup + 5f;
				while (true)
				{
					yield return (object)new WaitForEndOfFrame();
					if (active != resources || disposed || resources.Diagnostics == IntPtr.Zero)
					{
						break;
					}
					int num = NativeApi.CaptureState(resources.Diagnostics);
					if (num < 0)
					{
						throw new InvalidOperationException("Native capture failed; see native.log");
					}
					if (num != 3)
					{
						if (Time.realtimeSinceStartup > deadline)
						{
							throw new TimeoutException("Capture/GPU acknowledgement timed out");
						}
						CommandBuffer val = new CommandBuffer
						{
							name = "RiskOfRainUpscaling.Diagnostics.CapturePoll"
						};
						try
						{
							val.IssuePluginEventAndData(NativeApi.DiagnosticsGetEvent(), 2, resources.Diagnostics);
							Graphics.ExecuteCommandBuffer(val);
						}
						finally
						{
							val.Release();
						}
						yield return null;
						continue;
					}
					if (resources.CapturedScene == null)
					{
						throw new InvalidOperationException("Requested scene-frame metadata missing");
					}
					string text = Path.Combine(folder, "captures", DateTime.UtcNow.ToString("yyyyMMdd-HHmmss-fff"));
					Directory.CreateDirectory(text);
					SavePng(resources.Frozen[6], Path.Combine(text, "final.png"));
					SavePng(resources.Frozen[0], Path.Combine(text, "scene-color.png"));
					SavePng(resources.Frozen[1], Path.Combine(text, "scene-before-hud.png"));
					SavePng(resources.Frozen[4], Path.Combine(text, "depth-preview.png"));
					SavePng(resources.Frozen[5], Path.Combine(text, "motion-preview.png"));
					CaptureMetadata captureMetadata = Metadata(resources, ReadFloat(resources.Frozen[2]), ReadFloat(resources.Frozen[3]));
					File.WriteAllText(Path.Combine(text, "capture.json"), JsonUtility.ToJson((object)captureMetadata, true));
					Log("CAPTURE_COMPLETE unityFrame=" + captureMetadata.frame + " exportUnityFrame=" + Time.frameCount + " folder=" + text + " motionMaxUV=" + captureMetadata.motionMax + " motionNonfinite=" + captureMetadata.motionNonfinite + " depthNonfinite=" + captureMetadata.depthNonfinite);
					break;
				}
			}
			finally
			{
				RenderPipeline renderPipeline = this;
				if (resources.Diagnostics != IntPtr.Zero)
				{
					NativeApi.CaptureCancel(resources.Diagnostics);
				}
				resources.ReleaseCapture();
				renderPipeline.capturing = false;
			}
		}

		private static Texture2D Read(RenderTexture texture, bool floating)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture val = RenderTexture.active;
			Texture2D val2 = new Texture2D(((Texture)texture).width, ((Texture)texture).height, (TextureFormat)(floating ? 20 : 4), false, floating);
			try
			{
				RenderTexture.active = texture;
				val2.ReadPixels(new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), 0, 0, false);
				val2.Apply(false, false);
				return val2;
			}
			catch
			{
				Object.Destroy((Object)(object)val2);
				throw;
			}
			finally
			{
				RenderTexture.active = val;
			}
		}

		private static void SavePng(RenderTexture texture, string path)
		{
			Texture2D val = Read(texture, floating: false);
			try
			{
				File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val));
			}
			finally
			{
				Object.Destroy((Object)(object)val);
			}
		}

		private static Color[] ReadFloat(RenderTexture texture)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			RenderTexture val = (((int)texture.format == 11) ? null : RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)11, (RenderTextureReadWrite)1));
			try
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Graphics.Blit((Texture)(object)texture, val);
				}
				Texture2D val2 = Read(Object.op_Implicit((Object)(object)val) ? val : texture, floating: true);
				try
				{
					return val2.GetPixels();
				}
				finally
				{
					Object.Destroy((Object)(object)val2);
				}
			}
			finally
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					RenderTexture.ReleaseTemporary(val);
				}
			}
		}

		private static CaptureMetadata SceneMetadata(PipelineResources resources)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Invalid comparison between Unknown and I4
			CaptureMetadata obj = new CaptureMetadata
			{
				utc = DateTime.UtcNow.ToString("O")
			};
			Scene scene = ((Component)resources.Scene).gameObject.scene;
			obj.scene = ((Scene)(ref scene)).name;
			obj.frame = Time.frameCount;
			obj.colorSpace = ((object)QualitySettings.activeColorSpace/*cast due to .constrained prefix*/).ToString();
			obj.inputWidth = resources.InputWidth;
			obj.inputHeight = resources.InputHeight;
			obj.outputWidth = resources.Width;
			obj.outputHeight = resources.Height;
			obj.actualCameraWidth = resources.Scene.pixelWidth;
			obj.actualCameraHeight = resources.Scene.pixelHeight;
			obj.hudWidth = resources.Hud.pixelWidth;
			obj.hudHeight = resources.Hud.pixelHeight;
			obj.scaledCameraWidth = resources.Scene.scaledPixelWidth;
			obj.scaledCameraHeight = resources.Scene.scaledPixelHeight;
			obj.lowerResolution = resources.Low;
			obj.reversedZ = SystemInfo.usesReversedZBuffer;
			obj.near = resources.Near;
			obj.far = resources.Far;
			obj.depthMin = float.PositiveInfinity;
			obj.depthMax = float.NegativeInfinity;
			obj.motionPreviewGain = 20f;
			obj.depthPreviewRange = 200f;
			obj.projection = resources.Scene.projectionMatrix;
			obj.nonJitteredProjection = resources.Scene.nonJitteredProjectionMatrix;
			obj.worldToCamera = resources.Scene.worldToCameraMatrix;
			CaptureMetadata captureMetadata = obj;
			captureMetadata.scenePngEncoding = (((int)QualitySettings.activeColorSpace == 1) ? "linear" : "srgb");
			if (resources.Low || resources.Session != null)
			{
				captureMetadata.sceneColorCapturePoint = "explicit source of appended final scene OnRenderImage";
			}
			if (resources.Session != null)
			{
				captureMetadata.reconstructionMode = ((resources.Session.Quality == DlssQuality.DLAA) ? "DLAA" : "DLSS");
				captureMetadata.dlssQuality = resources.Session.Quality.ToString();
				captureMetadata.upscaler = NativeApi.UpscalerName(resources.Session.Context);
				captureMetadata.upscalerStateAtScene = resources.Session.State;
				captureMetadata.sceneBeforeHudCapturePoint = "upscaler output at end of effects before HUD";
				captureMetadata.upscalerColorInput = ((!resources.Session.BeforePostProcessing) ? "sRGB-encoded, decoded after evaluation" : (resources.Session.Upscaled ? "linear HDR scene after transparents (NaN/Inf removed); upscaled before display-sized post-processing" : "linear HDR scene after transparents (NaN/Inf removed); evaluated in place"));
			}
			return captureMetadata;
		}

		private static CaptureMetadata Metadata(PipelineResources resources, Color[] depth, Color[] motion)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			CaptureMetadata capturedScene = resources.CapturedScene;
			capturedScene.presentationMode = NativeApi.PresentationLabel;
			if (capturedScene.presentationMode == "D3D12 bridge")
			{
				capturedScene.finalCapturePoint += "; D3D11 producer image, not the physical D3D12 display buffer";
			}
			Color[] array = depth;
			foreach (Color val in array)
			{
				if (!Finite(val.r))
				{
					capturedScene.depthNonfinite++;
					continue;
				}
				capturedScene.depthMin = Math.Min(capturedScene.depthMin, val.r);
				capturedScene.depthMax = Math.Max(capturedScene.depthMax, val.r);
			}
			array = motion;
			foreach (Color val2 in array)
			{
				if (!Finite(val2.r) || !Finite(val2.g))
				{
					capturedScene.motionNonfinite++;
					continue;
				}
				Vector2 val3 = new Vector2(val2.r, val2.g);
				float magnitude = ((Vector2)(ref val3)).magnitude;
				capturedScene.motionMax = Math.Max(capturedScene.motionMax, magnitude);
				if ((double)magnitude > 1E-06)
				{
					capturedScene.motionNonzeroPixels++;
				}
			}
			if (!Finite(capturedScene.depthMin))
			{
				capturedScene.depthMin = 0f;
			}
			if (!Finite(capturedScene.depthMax))
			{
				capturedScene.depthMax = 0f;
			}
			return capturedScene;
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		internal void DrawOverlay()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			if (!disposed && overlay.Value && active != null && (int)Event.current.type == 7)
			{
				PipelineResources pipelineResources = active;
				float num = Math.Min((float)Screen.width / 3f, 400f);
				float num2 = num * (float)pipelineResources.Height / (float)pipelineResources.Width;
				GUI.Box(new Rect(0f, 0f, num * 3f, num2 * 2f + 66f), "");
				string text = (settings.HotkeysEnabled.Value ? ((object)settings.ToggleFrameGeneration.Value/*cast due to .constrained prefix*/).ToString() : "hotkeys disabled");
				string text2 = (settings.HotkeysEnabled.Value ? ((object)settings.CaptureEvidence.Value/*cast due to .constrained prefix*/).ToString() : "hotkeys disabled");
				GUI.Label(new Rect(8f, 2f, num * 3f - 16f, 24f), NativeApi.PresentationLabel + ((active?.Session != null) ? (" | SR " + NativeApi.UpscalerName(active.Session.Context)) : "") + " | FG " + NativeApi.FrameGenerationLabel + " (" + text + ") | " + fgTiming?.LimiterStatus + " | SDK presents " + NativeApi.FrameGenerationPresentedFrames());
				if (!pipelineResources.DiagnosticsReady)
				{
					GUI.Label(new Rect(8f, 28f, num * 3f - 16f, 24f), "Diagnostics unavailable for this camera; see native.log.");
					return;
				}
				Panel((Texture)(object)pipelineResources.Color, "Scene color " + pipelineResources.InputWidth + "×" + pipelineResources.InputHeight, 0f, 28f, num, num2);
				Panel((Texture)(object)pipelineResources.DepthView, "Depth (log distance)", num, 28f, num, num2);
				Panel((Texture)(object)pipelineResources.MotionView, "Motion (UV ×" + 20f + ")", num * 2f, 28f, num, num2);
				Panel((Texture)(object)pipelineResources.HudFree, "Before HUD", 0f, num2 + 46f, num, num2);
				Panel((Texture)(object)pipelineResources.Final, "After HUD; capture: " + text2, num, num2 + 46f, num, num2);
			}
		}

		private static void Panel(Texture texture, string label, float x, float y, float width, float height)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(x + 4f, y, width - 8f, height - 4f), texture, (ScaleMode)2, false);
			GUI.Label(new Rect(x + 6f, y + height - 2f, width - 12f, 20f), label);
		}

		internal RenderPipeline(Plugin plugin, ModSettings settings, ModLog log, string folder, bool native)
		{
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Invalid comparison between Unknown and I4
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Expected O, but got Unknown
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Expected O, but got Unknown
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Expected O, but got Unknown
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Expected O, but got Unknown
			RenderPipeline renderPipeline = this;
			this.plugin = plugin;
			this.log = log;
			this.folder = folder;
			this.settings = settings;
			upscaling = settings.Upscaling;
			quality = settings.Quality;
			upscaler = settings.Upscaler;
			preset = settings.Preset;
			outlines = settings.Outlines;
			upscaling.SettingChanged += ReconstructionChanged;
			quality.SettingChanged += ReconstructionChanged;
			upscaler.SettingChanged += ReconstructionChanged;
			preset.SettingChanged += ReconstructionChanged;
			outlines.SettingChanged += ReconstructionChanged;
			mipBiasOffset = settings.MipBiasOffset;
			mainMenu = settings.MainMenu;
			frameGeneration = settings.FrameGeneration;
			generation = settings.Generation;
			reflexLimiter = settings.ReflexFrameLimiter;
			overlay = settings.ShowOverlay;
			captureWhileOff = settings.CaptureWhileOff;
			available = native && (int)SystemInfo.graphicsDeviceType == 2 && !Object.op_Implicit((Object)(object)GraphicsSettings.currentRenderPipeline) && SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)14) && SystemInfo.SupportsRenderTextureFormat((RenderTextureFormat)13);
			Log("PIPELINE_READY available=" + available + "; overlay=" + ((object)settings.ToggleOverlay.Value/*cast due to .constrained prefix*/).ToString() + "; cycle quality=" + ((object)settings.CycleQuality.Value/*cast due to .constrained prefix*/).ToString() + "; capture=" + ((object)settings.CaptureEvidence.Value/*cast due to .constrained prefix*/).ToString() + "; reconstruction=" + ((object)settings.ToggleReconstruction.Value/*cast due to .constrained prefix*/).ToString() + "; FG=" + ((object)settings.ToggleFrameGeneration.Value/*cast due to .constrained prefix*/).ToString() + "; hotkeys enabled=" + settings.HotkeysEnabled.Value + "; quality=" + quality.Value.ToString() + ". Color=end of effects, depth/motion=early. Lower-resolution world is composed into the HUD camera's target before the HUD draws.");
			Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(BeforeCull));
			Camera.onPreRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreRender, (Delegate?)new CameraCallback(BeforeRender));
			Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPostRender, (Delegate?)new CameraCallback(AfterRender));
			if (available)
			{
				fgTiming = new FrameGenerationTiming(() => !renderPipeline.disposed && renderPipeline.modEnabled && ((Behaviour)plugin).isActiveAndEnabled && renderPipeline.generation.LiveEnabled && renderPipeline.upscaling.Value && renderPipeline.active?.Session != null && renderPipeline.active.Session.State >= 1 && Time.timeScale > 0f && Application.isFocused && plugin.ReconstructionCamera(renderPipeline.active.Scene, renderPipeline.mainMenu.Value) && (int)Screen.fullScreenMode > 0, () => !renderPipeline.disposed && renderPipeline.modEnabled && ((Behaviour)plugin).isActiveAndEnabled && settings.ReconstructionEnabled && renderPipeline.reflexLimiter.Value, log);
			}
		}

		private void Log(string message)
		{
			log.Info(message);
		}

		private void LogDebug(string message)
		{
			log.Debug(message);
		}

		private void LogWarning(string message)
		{
			log.Warning(message);
		}

		private void LogError(string message)
		{
			log.Error(message);
		}

		private bool HotkeyDown(ConfigEntry<KeyboardShortcut> shortcut)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (settings.HotkeysEnabled.Value && Application.isFocused)
			{
				KeyboardShortcut value = shortcut.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					return !plugin.IsBindingHotkey();
				}
			}
			return false;
		}

		internal bool OwnsTarget(Camera camera)
		{
			if (active != null && (Object)(object)active.Scene == (Object)(object)camera && (Object)(object)camera.targetTexture == (Object)(object)active.World)
			{
				return Object.op_Implicit((Object)(object)active.World);
			}
			return false;
		}

		private void ReconstructionChanged(object sender, EventArgs args)
		{
			attachFailed = false;
		}

		internal void Tick(bool enabled)
		{
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Invalid comparison between Unknown and I4
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Invalid comparison between Unknown and I4
			//IL_0831: Unknown result type (might be due to invalid IL or missing references)
			//IL_0837: Unknown result type (might be due to invalid IL or missing references)
			modEnabled = enabled;
			CollectRetired();
			if (disposed)
			{
				return;
			}
			UpdateProfiler();
			if (HotkeyDown(settings.ToggleOverlay))
			{
				overlay.Value = !overlay.Value;
			}
			if (HotkeyDown(settings.ToggleFrameGeneration))
			{
				frameGeneration.Value = !frameGeneration.Value;
				Log("FRAME_GEN_REQUESTED " + frameGeneration.Value + (generation.RestartRequired ? "; restart required to enable D3D12." : "; applies live; presentation runtime retained."));
			}
			if (HotkeyDown(settings.CycleQuality) && !capturing && upscaling.Value)
			{
				attachFailed = false;
				quality.Value = DlssPolicy.Next(quality.Value);
				Log("UPSCALER_QUALITY " + quality.Value);
			}
			if (HotkeyDown(settings.ToggleReconstruction) && !capturing)
			{
				upscaling.Value = !upscaling.Value;
				attachFailed = false;
				Log("UPSCALING_TOGGLED " + upscaling.Value);
			}
			if (HotkeyDown(settings.CaptureEvidence) && !capturing)
			{
				requestedCapture = true;
			}
			if (!modEnabled || (!captureWhileOff.Value && !upscaling.Value) || !available)
			{
				Detach("disabled/unsupported");
			}
			else
			{
				if (capturing)
				{
					return;
				}
				if (active?.Session != null && active.Session.State < 0)
				{
					upscaling.Value = false;
					active.Session.Restore();
					LogError("UPSCALING_FALLBACK native failure; Off selected; camera/AA restored; see native.log. The Toggle Upscaling shortcut retries explicitly.");
				}
				if (attachFailed)
				{
					return;
				}
				CameraRigController[] array = CameraRigController.readOnlyInstancesList.Where((CameraRigController r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.sceneCam) && plugin.ReconstructionCamera(r.sceneCam, mainMenu.Value)).ToArray();
				if (array.Length != 1)
				{
					Detach("no single eligible gameplay/main-menu/character-select scene camera");
					return;
				}
				CameraRigController val = array[0];
				if ((int)val.sceneCam.actualRenderingPath != 3)
				{
					Detach("Scene inputs require the deferred scene path");
					return;
				}
				if (!Object.op_Implicit((Object)(object)val.uiCam) || !((Behaviour)val.uiCam).isActiveAndEnabled || Object.op_Implicit((Object)(object)val.uiCam.targetTexture) || val.sceneCam.targetDisplay != 0 || val.uiCam.targetDisplay != 0 || val.sceneCam.stereoEnabled || val.uiCam.stereoEnabled || val.uiCam.rect != new Rect(0f, 0f, 1f, 1f) || ((Component)val.uiCam).gameObject.scene != ((Component)val.sceneCam).gameObject.scene || val.uiCam.depth <= val.sceneCam.depth)
				{
					Detach("HUD unavailable or belongs to another render target/display");
					return;
				}
				bool flag = upscaling.Value;
				if (flag && (val.sceneCam.orthographic || val.sceneCam.usePhysicalProperties || (int)QualitySettings.activeColorSpace != 1))
				{
					upscaling.Value = false;
					LogError("UPSCALING_FALLBACK upscaling requires a perspective camera and Linear color space.");
					flag = false;
				}
				DlssQuality dlssQuality = (flag ? quality.Value : DlssQuality.DLAA);
				bool flag2 = flag && dlssQuality != DlssQuality.DLAA;
				if (flag2 && !WorldRoutingPolicy.CanRoute(fullViewport: true, ownsBody: true, Object.op_Implicit((Object)(object)val.sceneCam.targetTexture) && !OwnsTarget(val.sceneCam), Object.op_Implicit((Object)(object)val.uiCam.targetTexture), Object.op_Implicit((Object)(object)val.skyboxCam) && Object.op_Implicit((Object)(object)val.skyboxCam.targetTexture) && (active == null || !((Object)(object)active.Sky == (Object)(object)val.skyboxCam) || !((Object)(object)val.skyboxCam.targetTexture == (Object)(object)active.World)), val.sceneCam.depth, val.uiCam.depth, Object.op_Implicit((Object)(object)val.skyboxCam) ? val.skyboxCam.depth : 0f, Object.op_Implicit((Object)(object)val.skyboxCam) && ((Behaviour)val.skyboxCam).isActiveAndEnabled))
				{
					DisableLowerResolution();
					Block("Unsupported camera ordering/foreign skybox target; lower-resolution rendering disabled (DLAA/native kept).");
					return;
				}
				int width = Screen.width;
				int height = Screen.height;
				if (width < 1 || height < 1)
				{
					Detach("display has no drawable pixels");
					return;
				}
				if (active?.Session != null && active.Session.Upscaler == UpscalerBackend.Auto)
				{
					int num = NativeApi.UpscalerKind(active.Session.Context);
					if (num > 0)
					{
						autoUpscaler = num;
					}
				}
				UpscalerBackend resolvedUpscaler = ResolvedUpscaler;
				int num2 = (flag2 ? DlssPolicy.Dimension(width, dlssQuality, resolvedUpscaler) : width);
				int num3 = (flag2 ? DlssPolicy.Dimension(height, dlssQuality, resolvedUpscaler) : height);
				if (active == null || (Object)(object)active.Scene != (Object)(object)val.sceneCam || (Object)(object)active.Hud != (Object)(object)val.uiCam || (Object)(object)active.Sky != (Object)(object)val.skyboxCam || active.SkyActive != (Object.op_Implicit((Object)(object)val.skyboxCam) && ((Behaviour)val.skyboxCam).isActiveAndEnabled) || active.SceneOrder != val.sceneCam.depth || active.HudOrder != val.uiCam.depth || active.Width != width || active.Height != height || active.InputWidth != num2 || active.InputHeight != num3 || active.Low != flag2 || active.Session != null != flag || (active.Session != null && (active.Session.Quality != dlssQuality || active.Session.Upscaler != upscaler.Value || active.Session.Preset != preset.Value || (active.Session.Upscaled && active.Session.Outlines != outlines.Value) || active.Session.BeforePostProcessing != DlssPolicy.BeforePostProcessing(dlssQuality, EffectivePlacement(val.sceneCam, dlssQuality)))) || active.Near != val.sceneCam.nearClipPlane || active.Far != val.sceneCam.farClipPlane)
				{
					Detach("camera/resolution/configuration changed");
					try
					{
						active = new PipelineResources(val, width, height, num2, num3, flag2);
						Attach(dlssQuality);
					}
					catch (Exception ex)
					{
						active?.Restore();
						if (active != null)
						{
							Retire(active);
						}
						active = null;
						attachFailed = true;
						upscaling.Value = false;
						Block("Attach failed: " + ex.Message + "; renderer restored and paused. The Toggle Upscaling shortcut explicitly retries; restart also resets it. See native.log.");
						return;
					}
				}
				Camera scene = active.Scene;
				scene.depthTextureMode = (DepthTextureMode)(scene.depthTextureMode | 5);
				if ((active.Low || active.Session != null) && !active.TailIsLast())
				{
					DisableLowerResolution();
					upscaling.Value = false;
					Block("Another scene image effect was added after our final capture; DLAA/DLSS disabled.");
					return;
				}
				UpscalerSession session = active.Session;
				if (session != null && session.Upscaled)
				{
					string text = active.Session.UnsupportedImageEffect((MonoBehaviour)(object)active.Tail);
					if (text != null)
					{
						placement = DlaaPlacement.EndOfEffects;
						Block("Scene image effect " + text + " cannot run at display size; upscaling moved to the end of effects for this session.");
						return;
					}
				}
				if (NativeApi.SceneInputsState(active.Context) == -2)
				{
					upscaling.Value = false;
					attachFailed = true;
					Block("Native input capture failed; renderer restored. The Toggle Upscaling shortcut explicitly retries. See native.log.");
					return;
				}
				if (log.IsEnabled(ModLogLevel.Debug) && Time.unscaledTime >= nextAudit)
				{
					nextAudit = Time.unscaledTime + 5f;
					AuditOrder(active);
				}
				if (active.Session != null && active.Session.State >= 0 && Time.unscaledTime >= nextMipScan)
				{
					nextMipScan = Time.unscaledTime + 10f;
					active.Session.ApplyMipBias();
				}
				if (active.Session != null && active.Session.State >= 0 && Time.unscaledTime >= nextMotionScan)
				{
					nextMotionScan = Time.unscaledTime + 2f;
					active.Session.ApplyParticleMotion();
				}
				if (overlay.Value || requestedCapture)
				{
					active.EnsureDiagnostics(LogWarning);
				}
				if (active.Diagnostics != IntPtr.Zero && NativeApi.DiagnosticsState(active.Diagnostics) == -2 && !active.DiagnosticsFailureReported)
				{
					active.DiagnosticsFailureReported = true;
					LogWarning("Diagnostics failed; overlay previews and capture are unavailable for this camera. Upscaling is unaffected. See native.log.");
				}
				if (requestedCapture && !capturing)
				{
					requestedCapture = false;
					if (active.DiagnosticsReady)
					{
						capturing = true;
						plugin.RunCapture(Capture(active));
					}
					else
					{
						LogWarning("CAPTURE_FAILED diagnostics unavailable for this camera; see native.log.");
					}
				}
			}
		}

		private DlaaPlacement EffectivePlacement(Camera camera, DlssQuality dlss)
		{
			if (!DlssPolicy.UpscalesBeforePostProcessing(dlss, placement))
			{
				return placement;
			}
			PostProcessLayer val = (Object.op_Implicit((Object)(object)camera) ? ((Component)camera).GetComponent<PostProcessLayer>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !((Behaviour)val).isActiveAndEnabled)
			{
				return DlaaPlacement.EndOfEffects;
			}
			return placement;
		}

		private void UpdateProfiler()
		{
			if (!available || !Profiling.Enabled)
			{
				profilerMarkers.Remove();
				profilerContext = null;
				return;
			}
			CameraRigController[] array = CameraRigController.readOnlyInstancesList.Where((CameraRigController r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.sceneCam) && plugin.ReconstructionCamera(r.sceneCam, mainMenu.Value)).ToArray();
			CameraRigController val = ((array.Length == 1) ? array[0] : null);
			profilerMarkers.Update(modEnabled && Object.op_Implicit((Object)(object)val), Object.op_Implicit((Object)(object)val) ? val.sceneCam : null, Object.op_Implicit((Object)(object)val) ? val.skyboxCam : null, Object.op_Implicit((Object)(object)val) ? val.uiCam : null);
			UpscalerSession upscalerSession = active?.Session;
			string text = ((upscalerSession == null) ? ("upscaling=Off (pipeline " + ((active == null) ? "detached" : "attached without upscaling") + ") screen=" + Screen.width + "x" + Screen.height) : ("upscaling=" + upscalerSession.Quality.ToString() + " upscaler=" + NativeApi.UpscalerName(upscalerSession.Context) + " dlssPreset=" + upscalerSession.Preset.ToString() + " world=" + active.InputWidth + "x" + active.InputHeight + " output=" + active.Width + "x" + active.Height + " placement=" + (upscalerSession.BeforePostProcessing ? "before post-processing" : "end of effects") + " displayPost=" + upscalerSession.PostRedirected + " sharpening=" + settings.Sharpness.Value.ToString("0.##") + " outlines=" + upscalerSession.OutlinePath));
			text = text + " | FG=" + NativeApi.FrameGenerationLabel + " presentation=" + NativeApi.PresentationLabel + " targetFrameRate=" + Application.targetFrameRate + " vSyncCount=" + QualitySettings.vSyncCount;
			if (!(text == profilerContext))
			{
				profilerContext = text;
				NativeApi.ProfilerSetContext(text);
			}
		}

		private void DisableLowerResolution()
		{
			if (quality.Value != DlssQuality.DLAA)
			{
				quality.Value = DlssQuality.DLAA;
				Log("UPSCALER_QUALITY DLAA (lower-resolution routing failed)");
			}
		}

		private void Block(string reason)
		{
			Detach(reason);
			if (lastBlocked != reason)
			{
				LogWarning(reason);
				lastBlocked = reason;
			}
		}

		private void Attach(DlssQuality dlss)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Expected O, but got Unknown
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			PipelineResources resources = active;
			Camera scene = resources.Scene;
			scene.depthTextureMode = (DepthTextureMode)(scene.depthTextureMode | 5);
			resources.Geometry = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.SceneInputs.AfterGBuffer"
			};
			resources.Geometry.IssuePluginEventAndData(NativeApi.SceneInputsGetEvent(), 90, resources.Context);
			resources.Scene.AddCommandBuffer((CameraEvent)5, resources.Geometry);
			resources.Before = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.SceneInputs.AfterForwardAlpha"
			};
			resources.Before.IssuePluginEventAndData(NativeApi.SceneInputsGetEvent(), 100, resources.Context);
			Profiling.Begin(resources.Before, "inputs.motionCopy (motion vectors -> RGHalf)");
			resources.Before.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)15), RenderTargetIdentifier.op_Implicit((Texture)(object)resources.Motion));
			resources.Before.IssuePluginEventAndData(NativeApi.SceneInputsGetEvent(), 102, resources.Context);
			Profiling.End(resources.Before, "inputs.motionCopy (motion vectors -> RGHalf)");
			resources.Before.SetRenderTarget(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2));
			resources.Scene.AddCommandBuffer((CameraEvent)17, resources.Before);
			resources.After = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.SceneInputs.SceneTail"
			};
			resources.After.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2), RenderTargetIdentifier.op_Implicit((Texture)(object)resources.Color));
			resources.After.Blit(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2), RenderTargetIdentifier.op_Implicit((Texture)(object)resources.HudFree));
			resources.After.SetRenderTarget(RenderTargetIdentifier.op_Implicit((BuiltinRenderTextureType)2));
			if (!resources.Low && !upscaling.Value)
			{
				resources.Scene.AddCommandBuffer((CameraEvent)20, resources.After);
			}
			if (resources.Low)
			{
				string text = DisplaySpace.Patch();
				if (text != null)
				{
					Log(text);
				}
				resources.Route();
			}
			resources.FgBefore = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.FrameGeneration.BeforeHud"
			};
			resources.Hud.AddCommandBuffer((CameraEvent)10, resources.FgBefore);
			resources.FgAfter = new CommandBuffer
			{
				name = "RiskOfRainUpscaling.FrameGeneration.AfterHud"
			};
			resources.Hud.AddCommandBuffer((CameraEvent)18, resources.FgAfter);
			if (upscaling.Value)
			{
				resources.Session = new UpscalerSession(resources.Scene, resources.Context, resources.Color, resources.Depth, resources.Motion, resources.Width, resources.Height, dlss, EffectivePlacement(resources.Scene, dlss), mipBiasOffset.Value, log, upscaler.Value, preset.Value, outlines.Value);
				resources.Session.Failure = delegate(Exception e)
				{
					upscaling.Value = false;
					LogError("UPSCALING_FALLBACK " + e.Message);
				};
				resources.Session.Initialize();
				if (resources.Session.BeforePostProcessing)
				{
					resources.UpscalePre = new CommandBuffer
					{
						name = "RiskOfRainUpscaling.Upscaling.BeforePostProcessing"
					};
					resources.Scene.AddCommandBuffer((CameraEvent)17, resources.UpscalePre);
				}
				nextMipScan = Time.unscaledTime + 10f;
				nextMotionScan = Time.unscaledTime + 2f;
				if (!Object.op_Implicit((Object)(object)resources.Tail))
				{
					resources.Tail = ((Component)resources.Scene).gameObject.AddComponent<SceneTail>();
				}
				resources.Tail.Process = (RenderTexture source, RenderTexture destination) => ProcessSceneTail(resources, source, destination);
			}
			traceFrames = 6;
			nextAudit = 0f;
			lastBlocked = null;
			string[] array = new string[27];
			array[0] = "PIPELINE_ATTACHED role=";
			array[1] = plugin.CameraRole(resources.Scene, mainMenu.Value) ?? "unknown";
			array[2] = " sceneName=";
			Scene scene2 = ((Component)resources.Scene).gameObject.scene;
			array[3] = ((Scene)(ref scene2)).name;
			array[4] = " scene=";
			array[5] = ((Object)resources.Scene).GetInstanceID().ToString();
			array[6] = " hud=";
			array[7] = ((Object)resources.Hud).GetInstanceID().ToString();
			array[8] = " world=";
			array[9] = resources.InputWidth.ToString();
			array[10] = "x";
			array[11] = resources.InputHeight.ToString();
			array[12] = " output=";
			array[13] = resources.Width.ToString();
			array[14] = "x";
			array[15] = resources.Height.ToString();
			array[16] = " targetRouting=";
			array[17] = resources.Low.ToString();
			array[18] = " quality=";
			array[19] = ((resources.Session != null) ? dlss.ToString() : "native");
			array[20] = " near=";
			array[21] = resources.Near.ToString();
			array[22] = " far=";
			array[23] = resources.Far.ToString();
			array[24] = " reversedZ=";
			array[25] = SystemInfo.usesReversedZBuffer.ToString();
			array[26] = "; depth/motion flags ORed.";
			Log(string.Concat(array));
		}

		private RenderTexture ProcessSceneTail(PipelineResources resources, RenderTexture source, RenderTexture destination)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			if (active != resources || !Object.op_Implicit((Object)(object)source))
			{
				return source;
			}
			try
			{
				if (((Texture)source).width != resources.InputWidth || ((Texture)source).height != resources.InputHeight)
				{
					throw new InvalidOperationException("Final scene source does not match the world render size");
				}
				if (resources.Session.Upscaled)
				{
					return ProcessDisplayPost(resources, source, destination);
				}
				CommandBuffer after = resources.After;
				after.Clear();
				after.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)source));
				Profiling.Begin(after, "tail.copy scene -> SceneInput");
				after.Blit((Texture)(object)source, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.Color));
				Profiling.End(after, "tail.copy scene -> SceneInput");
				bool prepared = resources.Session.Prepared;
				bool flag = resources.Low || DiagnosticsWanted;
				if (prepared)
				{
					after.IssuePluginEventAndData(resources.Session.BeforePostProcessing ? NativeApi.UpscalerGetSharpenEvent() : NativeApi.UpscalerGetEvaluateEvent(), Time.frameCount, resources.Session.Context);
					if (flag)
					{
						Profiling.Begin(after, "tail.copy output -> HudFree");
						after.Blit((Texture)(object)resources.Session.Output, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.HudFree));
						Profiling.End(after, "tail.copy output -> HudFree");
					}
				}
				else if (flag)
				{
					Profiling.Begin(after, "tail.copy scene -> HudFree");
					after.Blit((Texture)(object)source, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.HudFree));
					Profiling.End(after, "tail.copy scene -> HudFree");
				}
				after.SetRenderTarget(Object.op_Implicit((Object)(object)destination) ? new RenderTargetIdentifier((Texture)(object)destination) : new RenderTargetIdentifier((BuiltinRenderTextureType)2));
				Graphics.ExecuteCommandBuffer(after);
				if (traceFrames > 0 && resources.Low)
				{
					LogDebug("SCENE_TAIL frame=" + Time.frameCount + " source=" + ((Texture)source).width + "x" + ((Texture)source).height + " evaluated=" + prepared + " destination=" + (Object.op_Implicit((Object)(object)destination) ? (((Object)destination).name + " " + ((Texture)destination).width + "x" + ((Texture)destination).height) : "display"));
				}
				return (prepared && !resources.Low) ? resources.Session.Output : source;
			}
			catch (Exception ex)
			{
				upscaling.Value = false;
				resources.Session.Restore();
				LogError("UPSCALING_FALLBACK " + ex.Message);
				return source;
			}
		}

		private RenderTexture ProcessDisplayPost(PipelineResources resources, RenderTexture source, RenderTexture destination)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			UpscalerSession session = resources.Session;
			CommandBuffer after = resources.After;
			after.Clear();
			after.SetRenderTarget(RenderTargetIdentifier.op_Implicit((Texture)(object)source));
			Profiling.Begin(after, "tail.copy scene -> SceneInput");
			after.Blit((Texture)(object)source, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.Color));
			Profiling.End(after, "tail.copy scene -> SceneInput");
			bool postRedirected = session.PostRedirected;
			if (!postRedirected)
			{
				after.Blit((Texture)(object)source, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.HudFree));
			}
			Graphics.ExecuteCommandBuffer(after);
			after.Clear();
			if (postRedirected)
			{
				List<RenderTexture> list = new List<RenderTexture>();
				try
				{
					Profiling.BeginNow("post.display-sized image effects (outline/blur rerun)");
					RenderTexture val = session.RunDisplayEffects((MonoBehaviour)(object)resources.Tail, list);
					Profiling.EndNow("post.display-sized image effects (outline/blur rerun)");
					Profiling.Begin(after, "post.copy effects -> Output");
					after.Blit((Texture)(object)val, RenderTargetIdentifier.op_Implicit((Texture)(object)session.Output));
					Profiling.End(after, "post.copy effects -> Output");
					after.IssuePluginEventAndData(NativeApi.UpscalerGetSharpenEvent(), Time.frameCount, session.Context);
					Profiling.Begin(after, "post.copy Output -> HudFree");
					after.Blit((Texture)(object)session.Output, RenderTargetIdentifier.op_Implicit((Texture)(object)resources.HudFree));
					Profiling.End(after, "post.copy Output -> HudFree");
					after.SetRenderTarget(Object.op_Implicit((Object)(object)destination) ? new RenderTargetIdentifier((Texture)(object)destination) : new RenderTargetIdentifier((BuiltinRenderTextureType)2));
					Graphics.ExecuteCommandBuffer(after);
				}
				finally
				{
					foreach (RenderTexture item in list)
					{
						RenderTexture.ReleaseTemporary(item);
					}
				}
			}
			if (traceFrames > 0)
			{
				LogDebug("SCENE_TAIL frame=" + Time.frameCount + " source=" + ((Texture)source).width + "x" + ((Texture)source).height + " displayPostProcessing=" + postRedirected + " prepared=" + session.Prepared + " destination=" + (Object.op_Implicit((Object)(object)destination) ? (((Object)destination).name + " " + ((Texture)destination).width + "x" + ((Texture)destination).height) : "display"));
			}
			return source;
		}

		private bool HudOpacitySafe(Camera camera)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			if (overlay.Value)
			{
				return false;
			}
			foreach (MonoBehaviour item in from c in ((Component)camera).GetComponents<MonoBehaviour>()
				where Object.op_Implicit((Object)(object)c) && ((Behaviour)c).isActiveAndEnabled
				select c)
			{
				Type type = ((object)item).GetType();
				if (!(type.GetMethod("OnRenderImage", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null))
				{
					if (type.FullName != "RoR2.PostProcessing.DamageIndicator")
					{
						return false;
					}
					FieldInfo field = type.GetField("_indicatorValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field == null || !(field.GetValue(item) is float num) || !Mathf.Approximately(num, 0f))
					{
						return false;
					}
				}
			}
			Canvas[] array = Object.FindObjectsOfType<Canvas>();
			foreach (Canvas val in array)
			{
				if (((Behaviour)val).isActiveAndEnabled && (int)val.renderMode == 0 && val.targetDisplay == camera.targetDisplay)
				{
					return false;
				}
			}
			return true;
		}

		private void BeforeCull(Camera camera)
		{
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if (active == null || !Object.op_Implicit((Object)(object)camera))
			{
				return;
			}
			if ((Object)(object)camera == (Object)(object)active.Hud)
			{
				bool flag = HudOpacitySafe(camera);
				active.FgBefore.Clear();
				active.FgAfter.Clear();
				active.FgBefore.IssuePluginEventAndData(NativeApi.FrameGenerationGetBeforeHudEvent(), Time.frameCount, flag ? IntPtr.Zero : new IntPtr(1));
				active.FgAfter.IssuePluginEventAndData(NativeApi.FrameGenerationGetAfterHudEvent(), flag ? Time.frameCount : (-Time.frameCount), IntPtr.Zero);
			}
			if (active.Low && (Object)(object)camera == (Object)(object)active.Sky && (Object)(object)camera.targetTexture != (Object)(object)active.World)
			{
				DisableLowerResolution();
				Block("Skybox target was overridden before culling; lower-resolution mode disabled.");
			}
			else
			{
				if (!((Object)(object)camera == (Object)(object)active.Scene))
				{
					return;
				}
				if (active.Low && (Object)(object)camera.targetTexture != (Object)(object)active.World)
				{
					DisableLowerResolution();
					Block("Camera target was overridden before culling; lower-resolution mode disabled.");
					return;
				}
				camera.depthTextureMode = (DepthTextureMode)(camera.depthTextureMode | 5);
				active.Geometry.Clear();
				active.Geometry.IssuePluginEventAndData(NativeApi.SceneInputsGetFrameEvent(), Time.frameCount, active.Context);
				active.Geometry.IssuePluginEventAndData(NativeApi.SceneInputsGetEvent(), 90, active.Context);
				active.RecordDiagnostics(DiagnosticsWanted);
				if (active.Session != null && !active.Session.UsesPostProcessHook)
				{
					try
					{
						active.Session.Prepare();
					}
					catch (Exception ex)
					{
						upscaling.Value = false;
						active.Session.Restore();
						LogError("UPSCALING_FALLBACK " + ex.Message);
					}
				}
				if (!capturing && traceFrames > 0)
				{
					LogDebug("CAMERA_ORDER frame=" + Time.frameCount + " scene.preCull pixels=" + camera.pixelWidth + "x" + camera.pixelHeight + " target=" + (Object.op_Implicit((Object)(object)camera.targetTexture) ? ((Object)camera.targetTexture).name : "display"));
				}
			}
		}

		private void BeforeRender(Camera camera)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			if (active?.Session != null && (Object)(object)camera == (Object)(object)active.Scene && !active.Session.ProjectionIntact)
			{
				upscaling.Value = false;
				active.Session.Restore();
				LogError("UPSCALING_FALLBACK projection overwritten after DLAA preparation");
			}
			if (active?.UpscalePre != null && (Object)(object)camera == (Object)(object)active.Scene)
			{
				active.UpscalePre.Clear();
				Profiling.Begin(active.UpscalePre, "outlines.temporal inputs (mask + Sobel draws)");
				active.Session.RecordOutlineInputs(active.UpscalePre);
				Profiling.End(active.UpscalePre, "outlines.temporal inputs (mask + Sobel draws)");
				if (active.Session.Prepared)
				{
					active.UpscalePre.IssuePluginEventAndData(NativeApi.UpscalerGetEvaluateEvent(), Time.frameCount, active.Session.Context);
				}
				else if (active.Session.Upscaled)
				{
					active.UpscalePre.IssuePluginEventAndData(NativeApi.UpscalerGetFallbackEvent(), Time.frameCount, active.Session.Context);
				}
			}
			if (active != null && (Object)(object)camera == (Object)(object)active.Scene)
			{
				camera.depthTextureMode = (DepthTextureMode)(camera.depthTextureMode | 5);
			}
			if (capturing && active != null && (Object)(object)camera == (Object)(object)active.Scene && active.RequestFrame == Time.frameCount && active.CapturedScene == null)
			{
				active.CapturedScene = SceneMetadata(active);
			}
			if (!capturing && active != null && traceFrames > 0 && ((Object)(object)camera == (Object)(object)active.Scene || (Object)(object)camera == (Object)(object)active.Hud || (Object)(object)camera == (Object)(object)active.Sky))
			{
				LogDebug("CAMERA_ORDER frame=" + Time.frameCount + " preRender=" + ((Object)camera).name + " pixels=" + camera.pixelWidth + "x" + camera.pixelHeight + " depth=" + camera.depth);
			}
		}

		private void AfterRender(Camera came