Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Valheim Universal Upscaler v1.0.1
BepInEx/plugins/ValheimUpscalerRecon/ValheimUpscaler.Recon.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; 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("ValheimUpscaler.Recon")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a10b50c79e0bc65ddd7cab69f8374d7bea781499")] [assembly: AssemblyProduct("ValheimUpscaler.Recon")] [assembly: AssemblyTitle("ValheimUpscaler.Recon")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 ValheimUpscaler.Inject { internal static class BuildConfig { public const string Mode = "RELEASE"; public const bool IsDev = false; public const bool DebugOverlay = false; public const bool DevHotkeys = false; public const bool VerboseGpuLogs = false; public const bool InternalResolutionOverride = true; } internal static class Log { internal static ManualLogSource Source; [Conditional("BUILD_DEV")] public static void Trace(string msg) { } [Conditional("BUILD_DEV")] public static void Debug(string msg) { } public static void Info(string msg) { ManualLogSource source = Source; if (source != null) { source.LogInfo((object)msg); } } public static void Warning(string msg) { ManualLogSource source = Source; if (source != null) { source.LogWarning((object)msg); } } public static void Error(string msg) { ManualLogSource source = Source; if (source != null) { source.LogError((object)msg); } } } internal static class HotkeyRegistry { internal readonly struct Hotkey { public readonly KeyCode Key; public readonly string Description; public readonly Action Action; public Hotkey(KeyCode key, string description, Action action) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Key = key; Description = description; Action = action; } } private static readonly List<Hotkey> _hotkeys = new List<Hotkey>(); public static IReadOnlyList<Hotkey> All => _hotkeys; public static void Register(KeyCode key, string description, Action action) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _hotkeys.Count; i++) { if (_hotkeys[i].Key == key) { Log.Warning($"Hotkey {key} registered twice; keeping the first ('{_hotkeys[i].Description}')."); return; } } _hotkeys.Add(new Hotkey(key, description, action)); } public static void ProcessInput() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _hotkeys.Count; i++) { if (Input.GetKeyDown(_hotkeys[i].Key)) { try { _hotkeys[i].Action(); } catch (Exception arg) { Log.Error($"Hotkey {_hotkeys[i].Key} handler failed: {arg}"); } } } } } public class ReflexPacer : MonoBehaviour { private void Update() { UpscalerRunner.CurrentFrameId = (ulong)Time.frameCount; UpscalerNative.EmitLatencyMarker(0, UpscalerRunner.CurrentFrameId); } private void LateUpdate() { UpscalerNative.EmitLatencyMarker(1, UpscalerRunner.CurrentFrameId); } } public class MipmapBiasManager : MonoBehaviour { private float _lastBias; private float _checkTimer; private void Update() { _checkTimer -= Time.deltaTime; if (!(_checkTimer > 0f)) { _checkTimer = 5f; float num = Patches.CurrentQualityScale(); float num2 = ((num < 1f) ? Mathf.Log(num, 2f) : 0f); if (num2 != 0f || _lastBias != 0f) { _lastBias = num2; ApplyBias(num2); } } } private void ApplyBias(float bias) { Texture2D[] array = Resources.FindObjectsOfTypeAll<Texture2D>(); foreach (Texture2D val in array) { if ((Object)(object)val != (Object)null && ((Texture)val).mipMapBias != bias) { ((Texture)val).mipMapBias = bias; } } } } public enum DlssQuality { Native, Quality, Balanced, Performance, UltraPerformance, Custom } public enum UpscalerBackend { Auto, DLSS, FSR31, XeSS } [BepInPlugin("dev.daniel.valheim.upscaler.inject", "Valheim Upscaler Injection", "0.3.1")] [BepInProcess("valheim.exe")] public class InjectPlugin : BaseUnityPlugin { public const string GUID = "dev.daniel.valheim.upscaler.inject"; public const string NAME = "Valheim Upscaler Injection"; public const string VERSION = "0.3.1"; public static ConfigEntry<bool> ConfigEnableDLSS; public static ConfigEntry<bool> ConfigEnableFG; public static ConfigEntry<UpscalerBackend> ConfigBackend; public static ConfigEntry<DlssQuality> ConfigDLSSMode; public static ConfigEntry<float> ConfigCustomScale; public static ConfigEntry<bool> ConfigCustomResolutionPreset; private static bool _showMenu; private Rect _windowRect = new Rect(20f, 20f, 300f, 250f); private float _fgStatusPolledAt = -999f; private int _fgStatusCached = -1; private bool _fgSubmittingCached; public static bool IsMenuOpen() { return _showMenu; } private void ToggleMenu() { SetMenuOpen(!_showMenu); } private void SetMenuOpen(bool open) { if (_showMenu == open) { return; } _showMenu = open; if (_showMenu) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; return; } bool flag = false; try { Type type = AccessTools.TypeByName("Menu"); if (type != null) { MethodInfo methodInfo = AccessTools.Method(type, "IsVisible", (Type[])null, (Type[])null); if (methodInfo != null) { flag |= (bool)methodInfo.Invoke(null, null); } } Type type2 = AccessTools.TypeByName("InventoryGui"); if (type2 != null) { FieldInfo fieldInfo = AccessTools.Field(type2, "m_instance"); if (fieldInfo != null) { object value = fieldInfo.GetValue(null); if (value != null) { MethodInfo methodInfo2 = AccessTools.Method(type2, "IsVisible", (Type[])null, (Type[])null); if (methodInfo2 != null) { flag |= (bool)methodInfo2.Invoke(value, null); } } } } } catch (Exception ex) { Log.Warning("Error checking other menus: " + ex.Message); } if (!flag) { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } } private void Awake() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Invalid comparison between Unknown and I4 //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Invalid comparison between Unknown and I4 //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Expected O, but got Unknown //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Expected O, but got Unknown ConfigEnableDLSS = ((BaseUnityPlugin)this).Config.Bind<bool>("Upscaler", "Enable DLSS", true, "Enable DLSS/FSR upscaling"); ConfigEnableFG = ((BaseUnityPlugin)this).Config.Bind<bool>("Upscaler", "Enable Frame Generation", false, "Experimental DLSS-G frame generation (direct NGX, NVIDIA only). Off by default - also needs OptiScaler's [FrameGen] Enabled=true and FGInput=dlssg/nukems set (Insert overlay or OptiScaler.ini)."); ConfigBackend = ((BaseUnityPlugin)this).Config.Bind<UpscalerBackend>("Upscaler", "Preferred Upscaler", UpscalerBackend.Auto, "Which technology OptiScaler should output. Auto picks by GPU vendor (NVIDIA=DLSS, AMD=FSR 3.1, Intel=XeSS). Written to OptiScaler.ini; a change applies on the NEXT game launch."); ConfigDLSSMode = ((BaseUnityPlugin)this).Config.Bind<DlssQuality>("Upscaler", "Quality Mode", DlssQuality.Quality, "Resolution preset"); ConfigCustomScale = ((BaseUnityPlugin)this).Config.Bind<float>("Upscaler", "Custom Scale", 0.67f, new ConfigDescription("Custom render scale (0.1 - 1.0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); ConfigCustomResolutionPreset = ((BaseUnityPlugin)this).Config.Bind<bool>("Upscaler", "Custom Resolution Preset", false, "When enabled, the mod controls the game's internal rendering resolution (legacy mode). When disabled (default), the game's own resolution settings remain authoritative."); Log.Source = ((BaseUnityPlugin)this).Logger; Log.Info(string.Format("{0} {1} awake ({2} build). graphicsDeviceType={3}", "Valheim Upscaler Injection", "0.3.1", "RELEASE", SystemInfo.graphicsDeviceType)); RegisterHotkeys(); BackendSelector.Apply(); if ((int)SystemInfo.graphicsDeviceType != 18 && (int)SystemInfo.graphicsDeviceType != 21) { Log.Warning("Not running under Direct3D12 or Vulkan - launch Valheim with -force-d3d12 (or -force-vulkan), or the native upscaler can't work."); } try { Type type = AccessTools.TypeByName("FrameBufferScaler"); if (type == null) { Log.Error("FrameBufferScaler type NOT found - wrong game/version? Aborting patches."); return; } MethodInfo methodInfo = AccessTools.Method(type, "OnBufferCreated", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "OnBufferDestroyed", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Log.Error($"Method lookup failed (OnBufferCreated={methodInfo != null}, OnBufferDestroyed={methodInfo2 != null}). " + "Valheim may have renamed them - re-run ReconPlugin to get current names."); return; } Harmony val = new Harmony("dev.daniel.valheim.upscaler.inject"); val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Patches), "Created", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Patches), "Destroyed", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo3 = AccessTools.Method(AccessTools.TypeByName("UpscaledFrameBuffer"), "UpdateCurrentRenderScale", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "UpdateCurrentRenderScale", (Type[])null, (Type[])null); if (methodInfo3 != null) { val.Patch((MethodBase)methodInfo3, new HarmonyMethod(AccessTools.Method(typeof(Patches), "UpdateCurrentRenderScalePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.Warning("UpdateCurrentRenderScale NOT found on UpscaledFrameBuffer or FrameBufferScaler - quality modes won't drive render scale (game slider stays in control). Re-run ReconPlugin."); } Type type2 = AccessTools.TypeByName("Menu"); if (type2 != null) { MethodInfo methodInfo4 = AccessTools.Method(type2, "IsVisible", (Type[])null, (Type[])null); if (methodInfo4 != null) { val.Patch((MethodBase)methodInfo4, new HarmonyMethod(AccessTools.Method(typeof(Patches), "MenuIsVisiblePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.Warning("Menu.IsVisible method NOT found!"); } } else { Log.Warning("Menu type NOT found!"); } MethodInfo methodInfo5 = AccessTools.Method(typeof(Graphics), "DrawMeshInstanced", new Type[9] { typeof(Mesh), typeof(int), typeof(Material), typeof(Matrix4x4[]), typeof(int), typeof(MaterialPropertyBlock), typeof(ShadowCastingMode), typeof(bool), typeof(int) }, (Type[])null); if (methodInfo5 != null) { val.Patch((MethodBase)methodInfo5, new HarmonyMethod(AccessTools.Method(typeof(Patches), "DrawMeshInstancedPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.Warning("Graphics.DrawMeshInstanced method NOT found!"); } Log.Info("Harmony patches applied to FrameBufferScaler.OnBufferCreated/OnBufferDestroyed. Lower render scale below 100% in-world to trigger OnBufferCreated."); } catch (Exception ex) { Log.Error("Harmony patch FAILED: " + ex); } UpscalerRunner.Init(); } private void RegisterHotkeys() { HotkeyRegistry.Register((KeyCode)284, "Toggle the Upscaler Menu", ToggleMenu); HotkeyRegistry.Register((KeyCode)288, "Toggle upscaling (A/B vs vanilla)", InjectState.ToggleDisplay); HotkeyRegistry.Register((KeyCode)292, "Toggle DLSS-G frame generation (experimental)", ToggleFrameGeneration); HotkeyRegistry.Register((KeyCode)283, "Toggle the Upscaler Menu (custom resolution preset only)", delegate { if (ConfigCustomResolutionPreset.Value) { ToggleMenu(); } }); } private void ToggleFrameGeneration() { if (GpuInfo.Vendor != GpuVendor.Nvidia) { Log.Info($"Frame Generation (DLSS-G) unavailable: NVIDIA-only feature (GPU vendor: {GpuInfo.Vendor}). " + "OptiScaler's own FG (OptiFG) remains available via its Insert overlay."); return; } ConfigEnableFG.Value = !ConfigEnableFG.Value; Log.Info("Frame Generation (DLSS-G) " + (ConfigEnableFG.Value ? "ON" : "OFF") + " (experimental; also needs OptiScaler's FrameGen Enabled + FGInput=dlssg/nukems)"); } private void Update() { HotkeyRegistry.ProcessInput(); if (_showMenu) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void OnGUI() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0055: 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) if (_showMenu) { float num = Mathf.Max(1f, (float)Screen.height / 1080f); GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)); _windowRect = GUILayout.Window(98765, _windowRect, new WindowFunction(DrawMenu), "Upscaler Menu", Array.Empty<GUILayoutOption>()); } } private void DrawMenu(int windowID) { //IL_042e: Unknown result type (might be due to invalid IL or missing references) bool flag = GUILayout.Toggle(ConfigEnableDLSS.Value, "Enable Upscaling (F7)", Array.Empty<GUILayoutOption>()); if (flag != ConfigEnableDLSS.Value) { ConfigEnableDLSS.Value = flag; InjectState.SetDisplay(InjectState.Enabled ? InjectState.Output : InjectState.LowResInput); Log.Info("Injection " + (InjectState.Enabled ? "ON" : "OFF (vanilla)")); } bool flag2 = GUILayout.Toggle(ConfigCustomResolutionPreset.Value, "Custom Resolution Preset (Legacy Mode)", Array.Empty<GUILayoutOption>()); if (flag2 != ConfigCustomResolutionPreset.Value) { ConfigCustomResolutionPreset.Value = flag2; } GUILayout.Space(10f); GUILayout.Label($"GPU: {GpuInfo.Vendor} Backend: {BackendSelector.SelectedBackend}", Array.Empty<GUILayoutOption>()); GUILayout.Label("Preferred Upscaler (applies next launch):", Array.Empty<GUILayoutOption>()); foreach (UpscalerBackend value in Enum.GetValues(typeof(UpscalerBackend))) { if (GUILayout.Toggle(ConfigBackend.Value == value, value.ToString(), Array.Empty<GUILayoutOption>()) && ConfigBackend.Value != value) { ConfigBackend.Value = value; BackendSelector.Apply(); } } GUILayout.Space(10f); if (ConfigCustomResolutionPreset.Value) { GUILayout.Label("Quality Mode (Legacy Mode):", Array.Empty<GUILayoutOption>()); foreach (DlssQuality value2 in Enum.GetValues(typeof(DlssQuality))) { if (GUILayout.Toggle(ConfigDLSSMode.Value == value2, value2.ToString(), Array.Empty<GUILayoutOption>()) && ConfigDLSSMode.Value != value2) { ConfigDLSSMode.Value = value2; } } if (ConfigDLSSMode.Value == DlssQuality.Custom) { GUILayout.Space(10f); GUILayout.Label($"Custom Scale: {ConfigCustomScale.Value:F2}", Array.Empty<GUILayoutOption>()); float num = GUILayout.HorizontalSlider(ConfigCustomScale.Value, 0.1f, 1f, Array.Empty<GUILayoutOption>()); if (Mathf.Abs(num - ConfigCustomScale.Value) > 0.01f) { ConfigCustomScale.Value = num; } } } else { GUILayout.Label("Quality Mode: (Controlled by Game Resolution/Slider)", Array.Empty<GUILayoutOption>()); } GUILayout.Space(10f); if (GpuInfo.Vendor == GpuVendor.Nvidia) { bool flag3 = GUILayout.Toggle(ConfigEnableFG.Value, "Enable Frame Generation (F11)", Array.Empty<GUILayoutOption>()); if (flag3 != ConfigEnableFG.Value) { ConfigEnableFG.Value = flag3; Log.Info("Frame Generation (DLSS-G) " + (ConfigEnableFG.Value ? "ON" : "OFF") + " (experimental; also needs OptiScaler's FrameGen Enabled + FGInput=dlssg/nukems)"); } if (Time.unscaledTime - _fgStatusPolledAt > 1f) { _fgStatusPolledAt = Time.unscaledTime; _fgStatusCached = UpscalerNative.DlssGStatus(); _fgSubmittingCached = UpscalerNative.IsFgWritingOutput(); } string text = ((_fgStatusCached == 0) ? "NVIDIA DLSS-G (Native)" : ((_fgStatusCached == -1) ? "OptiScaler / Custom" : $"Error (Status: {_fgStatusCached})")); GUILayout.Label("Current FG Backend: " + text, Array.Empty<GUILayoutOption>()); GUILayout.Label($"FG status: avail={UpscalerNative.FgAvailable} submitting={_fgSubmittingCached}", Array.Empty<GUILayoutOption>()); GUILayout.Label("Needs OptiScaler's FrameGen Enabled + FGInput=dlssg/nukems (Insert overlay).", Array.Empty<GUILayoutOption>()); } else { GUILayout.Label($"Frame Generation: unavailable on {GpuInfo.Vendor} GPUs (DLSS-G is NVIDIA-only).", Array.Empty<GUILayoutOption>()); GUILayout.Label("OptiScaler's own FG (OptiFG) is available via its Insert overlay.", Array.Empty<GUILayoutOption>()); } GUILayout.Space(10f); GUILayout.Label("Hotkeys:", Array.Empty<GUILayoutOption>()); IReadOnlyList<HotkeyRegistry.Hotkey> all = HotkeyRegistry.All; for (int i = 0; i < all.Count; i++) { GUILayout.Label($" {all[i].Key}: {all[i].Description}", Array.Empty<GUILayoutOption>()); } GUI.DragWindow(); } private void OnDestroy() { UpscalerRunner.Dispose(); } } internal static class Diag { [Conditional("BUILD_DEV")] public static void Eval(string status) { } [Conditional("FEATURE_ENABLE_DEBUG_OVERLAY")] public static void Heartbeat() { } [Conditional("FEATURE_ENABLE_DEBUG_OVERLAY")] public static void DumpStatus() { } } internal static class BackendSelector { public static bool OptiScalerPresent { get; private set; } public static string SelectedBackend { get; private set; } = "(not applied)"; private static string GameDir => Path.GetDirectoryName(Application.dataPath); public static void Apply() { GpuInfo.Detect(); string gameDir = GameDir; OptiScalerPresent = File.Exists(Path.Combine(gameDir, "OptiScaler.ini")) || File.Exists(Path.Combine(gameDir, "OptiScaler.dll")) || File.Exists(Path.Combine(gameDir, "dxgi.dll")) || File.Exists(Path.Combine(gameDir, "winmm.dll")) || File.Exists(Path.Combine(gameDir, "version.dll")) || File.Exists(Path.Combine(gameDir, "nvngx.dll")); UpscalerBackend upscalerBackend = InjectPlugin.ConfigBackend?.Value ?? UpscalerBackend.Auto; UpscalerBackend upscalerBackend2 = upscalerBackend; if (upscalerBackend == UpscalerBackend.Auto) { upscalerBackend2 = GpuInfo.Vendor switch { GpuVendor.Nvidia => UpscalerBackend.DLSS, GpuVendor.Amd => UpscalerBackend.FSR31, GpuVendor.Intel => UpscalerBackend.XeSS, _ => (!OptiScalerPresent) ? UpscalerBackend.DLSS : UpscalerBackend.FSR31, }; } Log.Info($"GPU: {GpuInfo.Vendor} (PCI 0x{GpuInfo.VendorId:X4}) '{SystemInfo.graphicsDeviceName}'. " + string.Format("Backend: {0}{1}; ", upscalerBackend2, (upscalerBackend == UpscalerBackend.Auto) ? " (auto)" : " (user override)") + "OptiScaler " + (OptiScalerPresent ? "present" : "absent") + "."); if (GpuInfo.Vendor != GpuVendor.Nvidia && !OptiScalerPresent) { SelectedBackend = "none (bilinear)"; UpscalerRunner.NativeEvalEnabled = false; Log.Warning("Non-NVIDIA GPU without OptiScaler: no upscaler backend can run. Install OptiScaler (as dxgi.dll next to valheim.exe) to get " + ((GpuInfo.Vendor == GpuVendor.Intel) ? "XeSS" : "FSR") + "; staying on bilinear scaling."); } else if (!OptiScalerPresent) { SelectedBackend = "DLSS (driver NGX)"; } else { string value = (SelectedBackend = upscalerBackend2 switch { UpscalerBackend.XeSS => "xess", UpscalerBackend.DLSS => "dlss", _ => "fsr31", }); TryWriteOptiScalerIni(gameDir, value); } } private static void TryWriteOptiScalerIni(string dir, string value) { try { string path = Path.Combine(dir, "OptiScaler.ini"); object obj = (File.Exists(path) ? ((object)File.ReadAllLines(path)) : ((object)new string[0])); List<string> list = new List<string>(((Array)obj).Length + 2); bool flag = false; bool flag2 = false; bool flag3 = false; int num = -1; string[] array = (string[])obj; for (int i = 0; i < array.Length; i++) { string item; string text = (item = array[i]).Trim(); if (text.StartsWith("[")) { flag = text.Equals("[Upscalers]", StringComparison.OrdinalIgnoreCase); if (flag && num < 0) { num = list.Count; } } else if (flag && !flag2) { int num2 = text.IndexOf('='); if (num2 > 0 && text.Substring(0, num2).Trim().Equals("Dx12Upscaler", StringComparison.OrdinalIgnoreCase)) { flag2 = true; if (!text.Substring(num2 + 1).Trim().Equals(value, StringComparison.OrdinalIgnoreCase)) { flag3 = true; item = "Dx12Upscaler=" + value; } } } list.Add(item); } if (!flag2) { flag3 = true; if (num >= 0) { list.Insert(num + 1, "Dx12Upscaler=" + value); } else { list.Add("[Upscalers]"); list.Add("Dx12Upscaler=" + value); } } if (flag3) { File.WriteAllLines(path, list.ToArray()); Log.Info("OptiScaler.ini updated: Dx12Upscaler=" + value + " (applies on the next launch)."); } } catch (Exception ex) { Log.Warning("Could not update OptiScaler.ini (set Dx12Upscaler manually or via the Insert overlay): " + ex.Message); } } } internal static class Patches { private static IResolutionManager _lastManager; private static bool _isDrawingMask; public static void Created(object __instance, RenderTexture texture) { try { InjectState.OnBufferCreated(__instance, texture); } catch (Exception ex) { Log.Error("OnBufferCreated hook error: " + ex); } } public static void Destroyed() { try { InjectState.OnBufferDestroyed(); } catch (Exception ex) { Log.Error("OnBufferDestroyed hook error: " + ex); } } internal static float CurrentQualityScale() { return ResolutionManagerProvider.Current.GetQualityScale(); } public static bool UpdateCurrentRenderScalePrefix(object __instance) { IResolutionManager current = ResolutionManagerProvider.Current; if (_lastManager != null && _lastManager != current && _lastManager is F2ControlledResolutionManager f2ControlledResolutionManager) { f2ControlledResolutionManager.Restore(__instance); } _lastManager = current; return current.UpdateRenderScale(__instance); } public static bool MenuIsVisiblePrefix(ref bool __result) { if (InjectPlugin.IsMenuOpen()) { __result = true; return false; } return true; } public static void DrawMeshInstancedPrefix(Mesh mesh, int submeshIndex, Material material, Matrix4x4[] matrices, int count, MaterialPropertyBlock properties, ShadowCastingMode castShadows, bool receiveShadows, int layer) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (_isDrawingMask || !InjectState.Enabled || !UpscalerRunner.NativeEvalEnabled || !UpscalerNative.Available || !((Object)(object)InjectState.MaskCamera != (Object)null) || !((Object)(object)InjectState.MaskMaterial != (Object)null) || layer != InjectState.GrassLayer || InjectState.GrassLayer < 0) { return; } _isDrawingMask = true; try { Graphics.DrawMeshInstanced(mesh, submeshIndex, InjectState.MaskMaterial, matrices, count, properties, castShadows, receiveShadows, layer, InjectState.MaskCamera); } catch (Exception) { } finally { _isDrawingMask = false; } } } internal static class InjectState { public static bool FlipOutput = false; internal static bool ForceResetSubmit = false; internal static RenderTexture LowResInput; internal static RenderTexture Output; public static RenderTexture ReactiveMask; public static RenderTexture FgInterpOutput; public static Camera MaskCamera; public static Material MaskMaterial; public static int GrassLayer = -1; private static bool _disabledAA; private static object _aaModel; private static bool _originalAAEnabled; private static object _rawImage; private static PropertyInfo _texProp; private static PropertyInfo _uvRectProp; private static bool _flipped; private static UpscaleDispatch _dispatch; private static bool _warnedNoMaskShader; public static bool Enabled => InjectPlugin.ConfigEnableDLSS?.Value ?? true; public static void OnBufferCreated(object frameBufferScaler, RenderTexture lowRes) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) LowResInput = lowRes; ForceResetSubmit = true; UpscalerRunner.InvalidateTextureCache(); _rawImage = AccessTools.Field(frameBufferScaler.GetType(), "m_rawImage")?.GetValue(frameBufferScaler); if (_rawImage == null) { Log.Warning("m_rawImage is NULL on FrameBufferScaler; cannot redirect display."); return; } if (_texProp == null) { _texProp = AccessTools.Property(_rawImage.GetType(), "texture"); } if (_texProp == null) { Log.Warning("RawImage.texture property not found; cannot redirect display."); return; } if (_uvRectProp == null) { _uvRectProp = AccessTools.Property(_rawImage.GetType(), "uvRect"); } EnsureOutput(); EnsureReactiveMask(((Texture)lowRes).width, ((Texture)lowRes).height); EnsureMaskMaterial(); GrassLayer = LayerMask.NameToLayer("InstanceRenderer"); AttachDispatch(lowRes); SetDisplay(Enabled ? Output : LowResInput); DisableConflictingAA(ResolveMainCamera(lowRes)); Log.Info($"OnBufferCreated: lowRes {((Texture)lowRes).width}x{((Texture)lowRes).height} {lowRes.format} -> output {((Texture)Output).width}x{((Texture)Output).height}; " + $"RawImage redirected (enabled={Enabled}). Dispatch attached={(Object)(object)_dispatch != (Object)null}."); } public static void OnBufferDestroyed() { RestoreConflictingAA(); SetOutputFlip(flip: false); if ((Object)(object)LowResInput != (Object)null) { SetDisplay(LowResInput); } UpscalerRunner.InvalidateTextureCache(); ReleaseOutput(); ReleaseReactiveMask(); ReleaseFgInterpOutput(); if ((Object)(object)MaskCamera != (Object)null) { Object.Destroy((Object)(object)((Component)MaskCamera).gameObject); MaskCamera = null; } if ((Object)(object)_dispatch != (Object)null) { Object.DestroyImmediate((Object)(object)_dispatch); _dispatch = null; } LowResInput = null; Log.Info("OnBufferDestroyed: restored vanilla RawImage texture, released output and reactive mask resources."); } private static void EnsureOutput() { //IL_003e: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown int width = Screen.width; int height = Screen.height; if (!((Object)(object)Output != (Object)null) || ((Texture)Output).width != width || ((Texture)Output).height != height) { ReleaseOutput(); Output = new RenderTexture(width, height, 0, (RenderTextureFormat)2, (RenderTextureReadWrite)1) { name = "Upscaler_Output", filterMode = (FilterMode)1, enableRandomWrite = true }; if (!Output.Create()) { Log.Error("Output RenderTexture.Create() FAILED (UAV ARGBHalf unsupported?)."); } Graphics.Blit((Texture)(object)Texture2D.blackTexture, Output); UpscalerRunner.InvalidateTextureCache(); } } public static void EnsureFgInterpOutput() { //IL_003e: 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) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown int width = Screen.width; int height = Screen.height; if (!((Object)(object)FgInterpOutput != (Object)null) || ((Texture)FgInterpOutput).width != width || ((Texture)FgInterpOutput).height != height) { ReleaseFgInterpOutput(); FgInterpOutput = new RenderTexture(width, height, 0, (RenderTextureFormat)2, (RenderTextureReadWrite)1) { name = "Upscaler_FgInterpOutput", enableRandomWrite = true }; if (!FgInterpOutput.Create()) { Log.Error("FgInterpOutput RenderTexture.Create() FAILED (UAV ARGBHalf unsupported?)."); } Graphics.Blit((Texture)(object)Texture2D.blackTexture, FgInterpOutput); UpscalerRunner.InvalidateTextureCache(); } } private static void ReleaseFgInterpOutput() { if (!((Object)(object)FgInterpOutput == (Object)null)) { FgInterpOutput.Release(); Object.Destroy((Object)(object)FgInterpOutput); FgInterpOutput = null; } } public static void EnsureReactiveMask(int w, int h) { //IL_0032: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown if (!((Object)(object)ReactiveMask != (Object)null) || ((Texture)ReactiveMask).width != w || ((Texture)ReactiveMask).height != h) { ReleaseReactiveMask(); ReactiveMask = new RenderTexture(w, h, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1) { name = "Upscaler_ReactiveMask", filterMode = (FilterMode)1 }; if (!ReactiveMask.Create()) { Log.Error("ReactiveMask RenderTexture.Create() FAILED."); } UpscalerRunner.InvalidateTextureCache(); } } private static void ReleaseReactiveMask() { if (!((Object)(object)ReactiveMask == (Object)null)) { ReactiveMask.Release(); Object.Destroy((Object)(object)ReactiveMask); ReactiveMask = null; } } private static void EnsureMaskMaterial() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MaskMaterial != (Object)null) { return; } string[] array = new string[4] { "Unlit/Color", "Sprites/Default", "UI/Default", "Hidden/Internal-Colored" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if (!((Object)(object)val == (Object)null)) { MaskMaterial = new Material(val); MaskMaterial.enableInstancing = true; MaskMaterial.color = Color.white; return; } } if (!_warnedNoMaskShader) { _warnedNoMaskShader = true; Log.Warning("No usable mask shader in this build; reactive mask disabled (upscaling unaffected)."); } } internal static void DisableConflictingAA(Camera cam) { if (_disabledAA || (Object)(object)cam == (Object)null) { return; } try { Type type = AccessTools.TypeByName("PostProcessingBehaviour"); if (type == null) { return; } Component component = ((Component)cam).GetComponent(type); if ((Object)(object)component == (Object)null) { return; } object obj = AccessTools.Field(type, "profile")?.GetValue(component); if (obj == null) { return; } _aaModel = AccessTools.Field(obj.GetType(), "antialiasing")?.GetValue(obj); if (_aaModel == null) { return; } FieldInfo fieldInfo = AccessTools.Field(_aaModel.GetType(), "m_Enabled") ?? AccessTools.Field(_aaModel.GetType(), "enabled"); if (fieldInfo != null && fieldInfo.FieldType == typeof(bool)) { _originalAAEnabled = (bool)fieldInfo.GetValue(_aaModel); if (_originalAAEnabled) { fieldInfo.SetValue(_aaModel, false); _disabledAA = true; Log.Info("Disabled PPv1 antialiasing (TAA/FXAA). DLSS provides temporal AA — double accumulation and pre-blurring eliminated."); } } } catch (Exception ex) { Log.Warning("Failed to disable conflicting AA: " + ex.Message); } } internal static void RestoreConflictingAA() { if (!_disabledAA || _aaModel == null) { return; } try { (AccessTools.Field(_aaModel.GetType(), "m_Enabled") ?? AccessTools.Field(_aaModel.GetType(), "enabled"))?.SetValue(_aaModel, _originalAAEnabled); _disabledAA = false; Log.Info("Restored PPv1 antialiasing (was " + (_originalAAEnabled ? "enabled" : "disabled") + ")."); } catch (Exception ex) { Log.Warning("Failed to restore AA: " + ex.Message); } } private static void ReleaseOutput() { if (!((Object)(object)Output == (Object)null)) { Output.Release(); Object.Destroy((Object)(object)Output); Output = null; } } private static void AttachDispatch(RenderTexture lowRes) { Camera val = ResolveMainCamera(lowRes); if ((Object)(object)val == (Object)null) { Log.Warning("Main camera NOT found (no camera targets the low-res RT, GameCamera null). Dispatch not attached."); return; } UpscaleDispatch component = ((Component)val).GetComponent<UpscaleDispatch>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } _dispatch = ((Component)val).gameObject.AddComponent<UpscaleDispatch>(); if ((Object)(object)((Component)val).GetComponent<ReflexPacer>() == (Object)null) { ((Component)val).gameObject.AddComponent<ReflexPacer>(); } if ((Object)(object)((Component)val).GetComponent<MipmapBiasManager>() == (Object)null) { ((Component)val).gameObject.AddComponent<MipmapBiasManager>(); } Type type = AccessTools.TypeByName("PostProcessingBehaviour"); if (type != null) { Component component2 = ((Component)val).GetComponent(type); _ = (Object)(object)((component2 is MonoBehaviour) ? component2 : null) != (Object)null; } EnsureMaskCamera(val); } private static void EnsureMaskCamera(Camera mainCam) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if (!((Object)(object)MaskCamera != (Object)null)) { GameObject val = new GameObject("Upscaler_MaskCamera"); val.transform.SetParent(((Component)mainCam).transform, false); MaskCamera = val.AddComponent<Camera>(); ((Behaviour)MaskCamera).enabled = false; if ((Object)(object)ReactiveMask != (Object)null && (Object)(object)LowResInput != (Object)null) { MaskCamera.SetTargetBuffers(ReactiveMask.colorBuffer, LowResInput.depthBuffer); } else { MaskCamera.targetTexture = ReactiveMask; } MaskCamera.cullingMask = ((GrassLayer >= 0) ? (1 << GrassLayer) : 0); } } private static Camera ResolveMainCamera(RenderTexture lowRes) { Camera[] allCameras = Camera.allCameras; foreach (Camera val in allCameras) { if ((Object)(object)val != (Object)null && (Object)(object)val.targetTexture == (Object)(object)lowRes) { return val; } } Type type = AccessTools.TypeByName("GameCamera"); if (type != null) { object obj = AccessTools.Field(type, "m_instance")?.GetValue(null) ?? AccessTools.Property(type, "instance")?.GetValue(null); if (obj != null) { object? obj2 = AccessTools.Field(type, "m_camera")?.GetValue(obj); Camera val2 = (Camera)((obj2 is Camera) ? obj2 : null); if (val2 != null) { return val2; } } } return Camera.main; } internal static void SetDisplay(RenderTexture tex) { if (_rawImage != null && _texProp != null) { _texProp.SetValue(_rawImage, tex, null); } } internal static void SetOutputFlip(bool flip) { //IL_005f: 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) if (_rawImage != null && !(_uvRectProp == null) && flip != _flipped) { _flipped = flip; _uvRectProp.SetValue(_rawImage, (object)(flip ? new Rect(0f, 1f, 1f, -1f) : new Rect(0f, 0f, 1f, 1f)), null); } } internal static void ToggleDisplay() { if (InjectPlugin.ConfigEnableDLSS != null) { InjectPlugin.ConfigEnableDLSS.Value = !InjectPlugin.ConfigEnableDLSS.Value; } SetDisplay(Enabled ? Output : LowResInput); Log.Info("Injection " + (Enabled ? "ON" : "OFF (vanilla)")); } } public class UpscaleDispatch : MonoBehaviour { private Camera _cam; private Matrix4x4 _baseProj; private bool _jittered; private bool _loggedOnce; private bool _depthModeForced; private DepthTextureMode _depthModeBeforeForce; private void Awake() { _cam = ((Component)this).GetComponent<Camera>(); } private void OnPreCull() { _jittered = false; bool upscalerDepthMode = InjectState.Enabled && (Object)(object)InjectState.LowResInput != (Object)null && UpscalerRunner.ForceMotionVectors; SetUpscalerDepthMode(upscalerDepthMode); if (InjectState.Enabled && !((Object)(object)InjectState.LowResInput == (Object)null)) { UpscalerRunner.ApplyJitter(_cam, ((Texture)InjectState.LowResInput).width, ((Texture)InjectState.LowResInput).height, ref _baseProj, ref _jittered); } } private void OnPostRender() { if (_jittered) { _cam.ResetProjectionMatrix(); _jittered = false; } } private void OnDisable() { SetUpscalerDepthMode(enabled: false); if (_jittered && (Object)(object)_cam != (Object)null) { _cam.ResetProjectionMatrix(); _jittered = false; } } private void SetUpscalerDepthMode(bool enabled) { //IL_0055: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cam == (Object)null) { return; } if (enabled) { if (!_depthModeForced) { _depthModeBeforeForce = _cam.depthTextureMode; _depthModeForced = true; } _cam.depthTextureMode = (DepthTextureMode)(_depthModeBeforeForce | 5); } else if (_depthModeForced) { DepthTextureMode val = _cam.depthTextureMode; if ((_depthModeBeforeForce & 1) == 0) { val = (DepthTextureMode)(val & -2); } if ((_depthModeBeforeForce & 4) == 0) { val = (DepthTextureMode)(val & -5); } _cam.depthTextureMode = (DepthTextureMode)(val | (_depthModeBeforeForce & 5)); _depthModeForced = false; } } private void OnRenderImage(RenderTexture src, RenderTexture dst) { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) if (!_loggedOnce) { _loggedOnce = true; Shader.GetGlobalTexture("_CameraDepthTexture"); Shader.GetGlobalTexture("_CameraMotionVectorsTexture"); } if (!InjectState.Enabled) { InjectState.SetOutputFlip(flip: false); Graphics.Blit((Texture)(object)src, dst); return; } bool flag = !InjectState.ForceResetSubmit && UpscalerRunner.NativeEvalEnabled && UpscalerNative.IsWritingOutput(); bool num = UpscalerRunner.NativeEvalEnabled && UpscalerNative.Available; if ((Object)(object)InjectState.Output != (Object)null && !flag) { Graphics.Blit((Texture)(object)src, InjectState.Output); } if (UpscalerRunner.FgEnabled && (Object)(object)InjectState.FgInterpOutput == (Object)null) { InjectState.EnsureFgInterpOutput(); } if (num && (Object)(object)InjectState.MaskCamera != (Object)null && (Object)(object)InjectState.ReactiveMask != (Object)null && (Object)(object)InjectState.LowResInput != (Object)null && InjectState.GrassLayer >= 0 && (Object)(object)InjectState.MaskMaterial != (Object)null) { Camera maskCamera = InjectState.MaskCamera; maskCamera.CopyFrom(_cam); maskCamera.depthTextureMode = (DepthTextureMode)0; maskCamera.renderingPath = (RenderingPath)1; maskCamera.allowHDR = false; maskCamera.allowMSAA = false; maskCamera.useOcclusionCulling = false; maskCamera.cullingMask = 1 << InjectState.GrassLayer; maskCamera.SetTargetBuffers(InjectState.ReactiveMask.colorBuffer, InjectState.LowResInput.depthBuffer); maskCamera.clearFlags = (CameraClearFlags)4; RenderTexture active = RenderTexture.active; Graphics.SetRenderTarget(InjectState.ReactiveMask.colorBuffer, InjectState.LowResInput.depthBuffer); GL.Clear(false, true, Color.clear); RenderTexture.active = active; maskCamera.RenderWithShader(InjectState.MaskMaterial.shader, ""); } Matrix4x4 nonJitteredProj = (UpscalerRunner.JitterEnabled ? _cam.nonJitteredProjectionMatrix : _cam.projectionMatrix); bool num2 = UpscalerRunner.TryEvaluate(src, InjectState.Output, _cam, nonJitteredProj); InjectState.ForceResetSubmit = false; if (!num2 && flag && (Object)(object)InjectState.Output != (Object)null) { Graphics.Blit((Texture)(object)src, InjectState.Output); } flag = num2 && UpscalerRunner.NativeEvalEnabled && UpscalerNative.IsWritingOutput(); InjectState.SetOutputFlip(InjectState.FlipOutput && flag); Graphics.Blit((Texture)(object)src, dst); } } public interface IResolutionManager { bool UpdateRenderScale(object upscaledFrameBuffer); float GetQualityScale(); } public class GameControlledResolutionManager : IResolutionManager { public bool UpdateRenderScale(object upscaledFrameBuffer) { return true; } public float GetQualityScale() { if (!InjectState.Enabled) { return 1f; } if ((Object)(object)InjectState.LowResInput != (Object)null && (Object)(object)InjectState.Output != (Object)null && ((Texture)InjectState.Output).width > 0) { return (float)((Texture)InjectState.LowResInput).width / (float)((Texture)InjectState.Output).width; } return 1f; } } public class F2ControlledResolutionManager : IResolutionManager { private FieldInfo _ufbTargetVertical; private FieldInfo _ufbAutoTarget; private bool _ufbLookupFailed; private bool _overrideActive; private uint _savedTargetVertical; private bool _savedAutoTarget; public bool UpdateRenderScale(object upscaledFrameBuffer) { try { if (_ufbLookupFailed) { return true; } if (_ufbTargetVertical == null || _ufbAutoTarget == null) { Type type = upscaledFrameBuffer.GetType(); _ufbTargetVertical = AccessTools.Field(type, "m_targetResolutionVertical"); _ufbAutoTarget = AccessTools.Field(type, "m_autoTargetResolution"); if (_ufbTargetVertical == null || _ufbAutoTarget == null) { _ufbLookupFailed = true; Log.Error("UpscaledFrameBuffer fields renamed (re-run ReconPlugin); leaving vanilla render-scale logic active."); return true; } } if (InjectState.Enabled) { if (!_overrideActive) { _overrideActive = true; _savedTargetVertical = (uint)_ufbTargetVertical.GetValue(null); _savedAutoTarget = (bool)_ufbAutoTarget.GetValue(null); } uint num = (uint)Mathf.Clamp(Mathf.RoundToInt((float)Screen.height * GetQualityScale()), 8, Screen.height - 1); _ufbAutoTarget.SetValue(null, false); _ufbTargetVertical.SetValue(null, num); return false; } Restore(upscaledFrameBuffer); } catch (Exception ex) { Log.Error("Error overriding UpscaledFrameBuffer resolution: " + ex); } return true; } public void Restore(object upscaledFrameBuffer) { if (_overrideActive) { _overrideActive = false; if (_ufbAutoTarget != null) { _ufbAutoTarget.SetValue(null, _savedAutoTarget); } if (_ufbTargetVertical != null) { _ufbTargetVertical.SetValue(null, _savedTargetVertical); } } } public float GetQualityScale() { if (!InjectState.Enabled) { return 1f; } return InjectPlugin.ConfigDLSSMode.Value switch { DlssQuality.Native => 1f, DlssQuality.Quality => 0.67f, DlssQuality.Balanced => 0.58f, DlssQuality.Performance => 0.5f, DlssQuality.UltraPerformance => 0.33f, DlssQuality.Custom => InjectPlugin.ConfigCustomScale.Value, _ => 1f, }; } } public static class ResolutionManagerProvider { private static readonly IResolutionManager _gameControlled = new GameControlledResolutionManager(); private static readonly IResolutionManager _f2Controlled = new F2ControlledResolutionManager(); public static IResolutionManager Current { get { if (InjectPlugin.ConfigCustomResolutionPreset != null && InjectPlugin.ConfigCustomResolutionPreset.Value) { return _f2Controlled; } return _gameControlled; } } public static IResolutionManager F2Controlled => _f2Controlled; } public enum GpuVendor { Unknown, Nvidia, Amd, Intel } internal static class GpuInfo { private static bool _detected; public static GpuVendor Vendor { get; private set; } public static uint VendorId { get; private set; } public static void Detect() { if (_detected) { return; } _detected = true; VendorId = (uint)SystemInfo.graphicsDeviceVendorID; switch (VendorId) { case 4318u: Vendor = GpuVendor.Nvidia; return; case 4098u: case 4130u: Vendor = GpuVendor.Amd; return; case 32902u: case 32903u: Vendor = GpuVendor.Intel; return; } string text = (SystemInfo.graphicsDeviceVendor + " " + SystemInfo.graphicsDeviceName).ToLowerInvariant(); if (text.Contains("nvidia") || text.Contains("geforce")) { Vendor = GpuVendor.Nvidia; } else if (text.Contains("amd") || text.Contains("radeon") || text.Contains("ati ")) { Vendor = GpuVendor.Amd; } else if (text.Contains("intel") || text.Contains("arc")) { Vendor = GpuVendor.Intel; } else { Vendor = GpuVendor.Unknown; } } } internal struct UpscalerFrameParams { public IntPtr Color; public IntPtr Depth; public IntPtr MotionVectors; public IntPtr Output; public IntPtr ReactiveMask; public int RenderWidth; public int RenderHeight; public int DisplayWidth; public int DisplayHeight; public float JitterX; public float JitterY; public float MvScaleX; public float MvScaleY; public int Reset; public int Flags; public float FrameDeltaMs; public IntPtr FgOutputInterp; public int FgEnabled; public int FgNotRenderingGameFrames; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] CamViewToClip; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] ClipToPrevClip; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public float[] PrevClipToClip; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] CamPos; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] CamUp; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] CamRight; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public float[] CamFwd; public float CamNear; public float CamFar; public float CamFovRad; public float CamAspect; public int CamOrtho; } internal static class UpscalerNative { private const string DLL = "ValheimUpscalerNative"; private static IntPtr _eventFunc; public static bool Available { get; private set; } public static IntPtr EventFunc => _eventFunc; public static bool FgAvailable { get; private set; } [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_Init(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr VUP_GetRenderEventFunc(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_IsAvailable(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_IsSubmitting(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern void VUP_Shutdown(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_IsFgAvailable(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_IsFgSubmitting(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_GetFrameParamsSize(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_GetDlssGStatus(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_GetGpuVendor(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern int VUP_HasUnityInterfaces(); [DllImport("ValheimUpscalerNative", CallingConvention = CallingConvention.Cdecl)] private static extern void VUP_EmitLatencyMarker(int markerType, ulong frameId); public static int NativeGpuVendor() { try { return Available ? VUP_GetGpuVendor() : 0; } catch { return 0; } } public static bool IsWritingOutput() { try { return Available && VUP_IsSubmitting() != 0; } catch { return false; } } public static bool IsFgWritingOutput() { try { return Available && VUP_IsFgSubmitting() != 0; } catch { return false; } } public static int DlssGStatus() { try { return Available ? VUP_GetDlssGStatus() : (-1); } catch { return -1; } } public static bool TryLoad() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 try { int num = VUP_Init(); _eventFunc = VUP_GetRenderEventFunc(); Available = num != 0 && _eventFunc != IntPtr.Zero; int num2 = VUP_IsAvailable(); if (Available && num2 == 0) { Log.Info("Native DLL loaded; backend not confirmed yet (device/NGX init happens lazily on the first dispatched frame). Will dispatch."); } if (Available) { int num3 = VUP_GetFrameParamsSize(); int num4 = Marshal.SizeOf(typeof(UpscalerFrameParams)); if (num3 != num4) { Log.Error($"UpscalerFrameParams SIZE MISMATCH: native={num3} managed={num4} " + "- struct layout drifted between Upscaler.cs and upscaler_native.cpp. Fix before relying on output."); } else { Log.Info($"UpscalerFrameParams size OK ({num4} bytes, native/managed match)."); } } try { FgAvailable = VUP_IsFgAvailable() != 0; } catch { FgAvailable = false; } if (Available && (int)SystemInfo.graphicsDeviceType == 21) { try { if (VUP_HasUnityInterfaces() == 0) { Log.Warning("Vulkan renderer, but UnityPluginLoad never ran - deploy ValheimUpscalerNative.dll into valheim_Data\\Plugins\\x86_64\\ (NOT next to valheim.exe). Native dispatch disabled; bilinear fallback."); Available = false; } } catch (EntryPointNotFoundException) { } } } catch (DllNotFoundException) { Available = false; } catch (EntryPointNotFoundException ex3) { Log.Warning("Native export missing: " + ex3.Message); Available = false; } catch (Exception ex4) { Log.Warning("Native bridge load error: " + ex4.Message); Available = false; } return Available; } public static void Shutdown() { try { if (Available) { VUP_Shutdown(); } } catch { } } public static void EmitLatencyMarker(int type, ulong frameId) { try { if (Available) { VUP_EmitLatencyMarker(type, frameId); } } catch { } } } internal static class UpscalerRunner { private struct CachedNativePtr { public int W; public int H; public IntPtr Ptr; } public static ulong CurrentFrameId; public static bool JitterEnabled = true; public static bool NativeEvalEnabled = true; public static bool ForceMotionVectors = true; public static float CurrentJitterX; public static float CurrentJitterY; private static int _jitterSignMode = 3; public static int JitterReportSignX = -1; public static int JitterReportSignY = -1; private static int _mvSignMode = 3; public static int MvSignX = -1; public static int MvSignY = -1; private static int _jitterIndex; private const int kParamsRing = 4; private static readonly IntPtr[] _paramsRing = new IntPtr[4]; private static int _paramsSlot; private static CommandBuffer _cmd; private static int _lastRW; private static int _lastRH; private static bool _warnedNoDepthMv; private static int _lastSceneIdx = -1; private static Vector3 _lastCamPos; private static bool _forceReset; private static readonly Dictionary<Texture, CachedNativePtr> _ptrCache = new Dictionary<Texture, CachedNativePtr>(); private static readonly float[] _camViewToClip = new float[16]; private static readonly float[] _clipToPrevClip = new float[16]; private static readonly float[] _prevClipToClip = new float[16]; private static readonly float[] _camPosArr = new float[3]; private static readonly float[] _camUpArr = new float[3]; private static readonly float[] _camRightArr = new float[3]; private static readonly float[] _camFwdArr = new float[3]; private static Matrix4x4 _prevViewProj = Matrix4x4.identity; private static bool _havePrevViewProj; public static bool FgEnabled { get { if (GpuInfo.Vendor == GpuVendor.Nvidia) { return InjectPlugin.ConfigEnableFG?.Value ?? false; } return false; } } public static int JitterSignMode => _jitterSignMode; public static string JitterSignLabel => string.Format("mode {0} (X{1},Y{2})", _jitterSignMode, (JitterReportSignX > 0) ? "+" : "-", (JitterReportSignY > 0) ? "+" : "-"); public static string MvSignLabel => string.Format("mode {0} (X{1},Y{2})", _mvSignMode, (MvSignX > 0) ? "+" : "-", (MvSignY > 0) ? "+" : "-"); public static void CycleJitterSign() { _jitterSignMode = (_jitterSignMode + 1) % 4; JitterReportSignX = (((_jitterSignMode & 1) == 0) ? 1 : (-1)); JitterReportSignY = (((_jitterSignMode & 2) == 0) ? 1 : (-1)); } public static void CycleMvSign() { _mvSignMode = (_mvSignMode + 1) % 4; MvSignX = (((_mvSignMode & 1) == 0) ? 1 : (-1)); MvSignY = (((_mvSignMode & 2) == 0) ? 1 : (-1)); } private static void FlattenRowMajor(Matrix4x4 m, float[] dst) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) Vector4 row = ((Matrix4x4)(ref m)).GetRow(0); Vector4 row2 = ((Matrix4x4)(ref m)).GetRow(1); Vector4 row3 = ((Matrix4x4)(ref m)).GetRow(2); Vector4 row4 = ((Matrix4x4)(ref m)).GetRow(3); dst[0] = row.x; dst[1] = row.y; dst[2] = row.z; dst[3] = row.w; dst[4] = row2.x; dst[5] = row2.y; dst[6] = row2.z; dst[7] = row2.w; dst[8] = row3.x; dst[9] = row3.y; dst[10] = row3.z; dst[11] = row3.w; dst[12] = row4.x; dst[13] = row4.y; dst[14] = row4.z; dst[15] = row4.w; } public static void Init() { for (int i = 0; i < 4; i++) { _paramsRing[i] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UpscalerFrameParams))); } if (UpscalerNative.TryLoad()) { Log.Info("Upscaler native bridge active. Choose the backend (DLSS/FSR/XeSS) in the OptiScaler overlay (Insert)."); } else { Log.Warning("Upscaler native bridge unavailable - using bilinear fallback. Build ValheimUpscalerNative.dll, then drop OptiScaler (as dxgi.dll) next to valheim.exe."); } } public static void ApplyJitter(Camera cam, int renderW, int renderH, ref Matrix4x4 baseProj, ref bool jittered) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00e9: Unknown result type (might be due to invalid IL or missing references) if (!JitterEnabled) { CurrentJitterX = 0f; CurrentJitterY = 0f; return; } cam.ResetProjectionMatrix(); baseProj = cam.projectionMatrix; cam.nonJitteredProjectionMatrix = baseProj; int num = Mathf.Clamp(Mathf.RoundToInt(8f * Mathf.Pow((float)Screen.width / (float)Mathf.Max(1, renderW), 2f)), 8, 64); _jitterIndex = (_jitterIndex + 1) % num; float num2 = Halton(_jitterIndex + 1, 2) - 0.5f; float num3 = Halton(_jitterIndex + 1, 3) - 0.5f; CurrentJitterX = (float)JitterReportSignX * num2; CurrentJitterY = (float)JitterReportSignY * num3; Matrix4x4 projectionMatrix = baseProj; projectionMatrix.m02 += 2f * num2 / (float)renderW; projectionMatrix.m12 += 2f * num3 / (float)renderH; cam.projectionMatrix = projectionMatrix; jittered = true; } public static bool TryEvaluate(RenderTexture src, RenderTexture output, Camera cam, Matrix4x4 nonJitteredProj) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027f: 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_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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_0524: Unknown result type (might be due to invalid IL or missing references) //IL_0529: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Expected O, but got Unknown if ((Object)(object)output == (Object)null) { return false; } if (!NativeEvalEnabled) { return false; } if (!UpscalerNative.Available) { return false; } Texture globalTexture = Shader.GetGlobalTexture("_CameraDepthTexture"); Texture globalTexture2 = Shader.GetGlobalTexture("_CameraMotionVectorsTexture"); if ((Object)(object)globalTexture == (Object)null || (Object)(object)globalTexture2 == (Object)null) { if (!_warnedNoDepthMv) { _warnedNoDepthMv = true; Log.Warning("Depth/MV not reachable as Textures; upscaler disabled this session (bilinear fallback)."); } return false; } int width = ((Texture)src).width; int height = ((Texture)src).height; IntPtr cachedNativePtr = GetCachedNativePtr((Texture)(object)src); IntPtr cachedNativePtr2 = GetCachedNativePtr(globalTexture); IntPtr cachedNativePtr3 = GetCachedNativePtr(globalTexture2); IntPtr cachedNativePtr4 = GetCachedNativePtr((Texture)(object)output); if (cachedNativePtr == IntPtr.Zero || cachedNativePtr2 == IntPtr.Zero || cachedNativePtr3 == IntPtr.Zero || cachedNativePtr4 == IntPtr.Zero) { return false; } bool num = width != _lastRW || height != _lastRH; Scene activeScene = SceneManager.GetActiveScene(); int buildIndex = ((Scene)(ref activeScene)).buildIndex; bool flag = _lastSceneIdx >= 0 && buildIndex != _lastSceneIdx; Vector3 val = (((Object)(object)cam != (Object)null) ? ((Component)cam).transform.position : Vector3.zero); bool flag2 = _lastSceneIdx >= 0 && Vector3.SqrMagnitude(val - _lastCamPos) > 2500f; int num2 = ((num || flag || flag2 || _forceReset) ? 1 : 0); _lastRW = width; _lastRH = height; _lastSceneIdx = buildIndex; _lastCamPos = val; _forceReset = false; IntPtr cachedNativePtr5 = GetCachedNativePtr((Texture)(object)InjectState.ReactiveMask); IntPtr cachedNativePtr6 = GetCachedNativePtr((Texture)(object)InjectState.FgInterpOutput); int fgEnabled = ((FgEnabled && cachedNativePtr6 != IntPtr.Zero) ? 1 : 0); int fgNotRenderingGameFrames = ((num2 != 0 || Time.timeScale == 0f || !InjectState.Enabled) ? 1 : 0); if ((Object)(object)cam != (Object)null) { FlattenRowMajor(nonJitteredProj, _camViewToClip); Matrix4x4 val2 = nonJitteredProj * cam.worldToCameraMatrix; if (_havePrevViewProj && num2 == 0) { FlattenRowMajor(_prevViewProj * ((Matrix4x4)(ref val2)).inverse, _clipToPrevClip); FlattenRowMajor(val2 * ((Matrix4x4)(ref _prevViewProj)).inverse, _prevClipToClip); } else { FlattenRowMajor(Matrix4x4.identity, _clipToPrevClip); FlattenRowMajor(Matrix4x4.identity, _prevClipToClip); } _prevViewProj = val2; _havePrevViewProj = true; Vector3 position = ((Component)cam).transform.position; Vector3 up = ((Component)cam).transform.up; Vector3 right = ((Component)cam).transform.right; Vector3 forward = ((Component)cam).transform.forward; _camPosArr[0] = position.x; _camPosArr[1] = position.y; _camPosArr[2] = position.z; _camUpArr[0] = up.x; _camUpArr[1] = up.y; _camUpArr[2] = up.z; _camRightArr[0] = right.x; _camRightArr[1] = right.y; _camRightArr[2] = right.z; _camFwdArr[0] = forward.x; _camFwdArr[1] = forward.y; _camFwdArr[2] = forward.z; } UpscalerFrameParams structure = new UpscalerFrameParams { Color = cachedNativePtr, Depth = cachedNativePtr2, MotionVectors = cachedNativePtr3, Output = cachedNativePtr4, ReactiveMask = cachedNativePtr5, RenderWidth = width, RenderHeight = height, DisplayWidth = ((Texture)output).width, DisplayHeight = ((Texture)output).height, JitterX = CurrentJitterX, JitterY = CurrentJitterY, MvScaleX = MvSignX * width, MvScaleY = MvSignY * height, Reset = num2, Flags = 0, FrameDeltaMs = Time.unscaledDeltaTime * 1000f, FgOutputInterp = cachedNativePtr6, FgEnabled = fgEnabled, FgNotRenderingGameFrames = fgNotRenderingGameFrames, CamViewToClip = _camViewToClip, ClipToPrevClip = _clipToPrevClip, PrevClipToClip = _prevClipToClip, CamPos = _camPosArr, CamUp = _camUpArr, CamRight = _camRightArr, CamFwd = _camFwdArr, CamNear = (((Object)(object)cam != (Object)null) ? cam.nearClipPlane : 0.1f), CamFar = (((Object)(object)cam != (Object)null) ? cam.farClipPlane : 1000f), CamFovRad = (((Object)(object)cam != (Object)null) ? (cam.fieldOfView * (MathF.PI / 180f)) : 0f), CamAspect = (((Object)(object)cam != (Object)null) ? cam.aspect : 1f), CamOrtho = (((Object)(object)cam != (Object)null && cam.orthographic) ? 1 : 0) }; _paramsSlot = (_paramsSlot + 1) % 4; IntPtr intPtr = _paramsRing[_paramsSlot]; Marshal.StructureToPtr(structure, intPtr, fDeleteOld: false); if (_cmd == null) { _cmd = new CommandBuffer { name = "ValheimUpscaler" }; } _cmd.Clear(); _cmd.IssuePluginEventAndData(UpscalerNative.EventFunc, 1, intPtr); Graphics.ExecuteCommandBuffer(_cmd); return true; } public static void InvalidateTextureCache() { _ptrCache.Clear(); } private static IntPtr GetCachedNativePtr(Texture tex) { if ((Object)(object)tex == (Object)null) { return IntPtr.Zero; } if (_ptrCache.TryGetValue(tex, out var value) && value.W == tex.width && value.H == tex.height && value.Ptr != IntPtr.Zero) { return value.Ptr; } if (_ptrCache.Count > 64) { _ptrCache.Clear(); } IntPtr nativeTexturePtr = tex.GetNativeTexturePtr(); _ptrCache[tex] = new CachedNativePtr { W = tex.width, H = tex.height, Ptr = nativeTexturePtr }; return nativeTexturePtr; } private static float Halton(int index, int b) { float num = 0f; float num2 = 1f; for (int num3 = index; num3 > 0; num3 /= b) { num2 /= (float)b; num += num2 * (float)(num3 % b); } return num; } public static void Dispose() { UpscalerNative.Shutdown(); if (_cmd != null) { _cmd.Release(); _cmd = null; } for (int i = 0; i < 4; i++) { if (_paramsRing[i] != IntPtr.Zero) { Marshal.FreeHGlobal(_paramsRing[i]); _paramsRing[i] = IntPtr.Zero; } } } } }