From 7b2e82b27f1f378d82e68055df48ae758af0ad71 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sat, 11 Jan 2025 15:22:04 +0100 Subject: [PATCH] Add some HDR related debug data and support info. --- .../PostProcessing/RenderTargetHdrEnabler.cs | 36 ++++++++++++++-- .../PostProcessing/ShaderReplacementFixer.cs | 34 ++++++++------- Penumbra/Penumbra.cs | 13 +++--- Penumbra/UI/Tabs/Debug/RenderTargetDrawer.cs | 41 ++++++++++++++++++- 4 files changed, 96 insertions(+), 28 deletions(-) diff --git a/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs b/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs index b7ae771b..41c4dab1 100644 --- a/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs +++ b/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs @@ -1,11 +1,13 @@ using System.Collections.Immutable; using Dalamud.Hooking; +using Dalamud.Plugin; using Dalamud.Plugin.Services; using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using OtterGui.Services; using Penumbra.GameData; +using Penumbra.Services; namespace Penumbra.Interop.Hooks.PostProcessing; @@ -21,9 +23,9 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable private static readonly IComparer ForcedTextureConfigComparer = Comparer.Create((lhs, rhs) => lhs.CreationOrder.CompareTo(rhs.CreationOrder)); - private readonly Configuration _config; - - private readonly ThreadLocal _textureIndices = new(() => new TextureIndices(-1, -1)); + private readonly Configuration _config; + private readonly Tuple _share; + private readonly ThreadLocal _textureIndices = new(() => new TextureIndices(-1, -1)); private readonly ThreadLocal?> _textures = new(() => null); @@ -35,17 +37,42 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable [Signature(Sigs.DeviceCreateTexture2D, DetourName = nameof(CreateTexture2DDetour))] private readonly Hook _createTexture2D = null!; - public RenderTargetHdrEnabler(IGameInteropProvider interop, Configuration config) + public RenderTargetHdrEnabler(IGameInteropProvider interop, Configuration config, IDalamudPluginInterface pi, + DalamudConfigService dalamudConfig) { _config = config; interop.InitializeFromAttributes(this); if (config.HdrRenderTargets && !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize) _renderTargetManagerInitialize.Enable(); + + _share = pi.GetOrCreateData("Penumbra.RenderTargetHDR.V1", () => + { + bool? waitForPlugins = dalamudConfig.GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool s) ? s : null; + return new Tuple(waitForPlugins, config.HdrRenderTargets, + !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize, [0], [false]); + }); + ++_share.Item4[0]; } + public bool? FirstLaunchWaitForPluginsState + => _share.Item1; + + public bool FirstLaunchHdrState + => _share.Item2; + + public bool FirstLaunchHdrHookOverrideState + => _share.Item3; + + public int PenumbraReloadCount + => _share.Item4[0]; + + public bool HdrEnabledSuccess + => _share.Item5[0]; + ~RenderTargetHdrEnabler() => Dispose(false); + public static ForcedTextureConfig? GetForcedTextureConfig(int creationOrder) { var i = ForcedTextureConfigs.BinarySearch(new ForcedTextureConfig(creationOrder, 0, string.Empty), ForcedTextureConfigComparer); @@ -67,6 +94,7 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable private nint RenderTargetManagerInitializeDetour(RenderTargetManager* @this) { _createTexture2D.Enable(); + _share.Item5[0] = true; _textureIndices.Value = new TextureIndices(0, 0); _textures.Value = _config.DebugMode ? [] : null; try diff --git a/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs b/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs index f70ea06e..cae37776 100644 --- a/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs +++ b/Penumbra/Interop/Hooks/PostProcessing/ShaderReplacementFixer.cs @@ -109,31 +109,29 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic CommunicatorService communicator, HookManager hooks, CharacterBaseVTables vTables, HumanSetupScalingHook humanSetupScalingHook) { _resourceHandleDestructor = resourceHandleDestructor; - var utility1 = utility; - var modelRenderer1 = modelRenderer; _communicator = communicator; _humanSetupScalingHook = humanSetupScalingHook; _skinState = new ModdedShaderPackageState( - () => (ShaderPackageResourceHandle**)&utility1.Address->SkinShpkResource, - () => (ShaderPackageResourceHandle*)utility1.DefaultSkinShpkResource); + () => (ShaderPackageResourceHandle**)&utility.Address->SkinShpkResource, + () => (ShaderPackageResourceHandle*)utility.DefaultSkinShpkResource); _characterStockingsState = new ModdedShaderPackageState( - () => (ShaderPackageResourceHandle**)&utility1.Address->CharacterStockingsShpkResource, - () => (ShaderPackageResourceHandle*)utility1.DefaultCharacterStockingsShpkResource); + () => (ShaderPackageResourceHandle**)&utility.Address->CharacterStockingsShpkResource, + () => (ShaderPackageResourceHandle*)utility.DefaultCharacterStockingsShpkResource); _characterLegacyState = new ModdedShaderPackageState( - () => (ShaderPackageResourceHandle**)&utility1.Address->CharacterLegacyShpkResource, - () => (ShaderPackageResourceHandle*)utility1.DefaultCharacterLegacyShpkResource); - _irisState = new ModdedShaderPackageState(() => modelRenderer1.IrisShaderPackage, () => modelRenderer1.DefaultIrisShaderPackage); - _characterGlassState = new ModdedShaderPackageState(() => modelRenderer1.CharacterGlassShaderPackage, - () => modelRenderer1.DefaultCharacterGlassShaderPackage); - _characterTransparencyState = new ModdedShaderPackageState(() => modelRenderer1.CharacterTransparencyShaderPackage, - () => modelRenderer1.DefaultCharacterTransparencyShaderPackage); - _characterTattooState = new ModdedShaderPackageState(() => modelRenderer1.CharacterTattooShaderPackage, - () => modelRenderer1.DefaultCharacterTattooShaderPackage); - _characterOcclusionState = new ModdedShaderPackageState(() => modelRenderer1.CharacterOcclusionShaderPackage, - () => modelRenderer1.DefaultCharacterOcclusionShaderPackage); + () => (ShaderPackageResourceHandle**)&utility.Address->CharacterLegacyShpkResource, + () => (ShaderPackageResourceHandle*)utility.DefaultCharacterLegacyShpkResource); + _irisState = new ModdedShaderPackageState(() => modelRenderer.IrisShaderPackage, () => modelRenderer.DefaultIrisShaderPackage); + _characterGlassState = new ModdedShaderPackageState(() => modelRenderer.CharacterGlassShaderPackage, + () => modelRenderer.DefaultCharacterGlassShaderPackage); + _characterTransparencyState = new ModdedShaderPackageState(() => modelRenderer.CharacterTransparencyShaderPackage, + () => modelRenderer.DefaultCharacterTransparencyShaderPackage); + _characterTattooState = new ModdedShaderPackageState(() => modelRenderer.CharacterTattooShaderPackage, + () => modelRenderer.DefaultCharacterTattooShaderPackage); + _characterOcclusionState = new ModdedShaderPackageState(() => modelRenderer.CharacterOcclusionShaderPackage, + () => modelRenderer.DefaultCharacterOcclusionShaderPackage); _hairMaskState = - new ModdedShaderPackageState(() => modelRenderer1.HairMaskShaderPackage, () => modelRenderer1.DefaultHairMaskShaderPackage); + new ModdedShaderPackageState(() => modelRenderer.HairMaskShaderPackage, () => modelRenderer.DefaultHairMaskShaderPackage); _humanSetupScalingHook.SetupReplacements += SetupHssReplacements; _humanOnRenderMaterialHook = hooks.CreateHook("Human.OnRenderMaterial", vTables.HumanVTable[64], diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index 33ce9f40..b6009627 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -23,6 +23,7 @@ using Lumina.Excel.Sheets; using Penumbra.GameData.Data; using Penumbra.GameData.Files; using Penumbra.Interop.Hooks; +using Penumbra.Interop.Hooks.PostProcessing; using Penumbra.Interop.Hooks.ResourceLoading; namespace Penumbra; @@ -205,9 +206,10 @@ public class Penumbra : IDalamudPlugin public string GatherSupportInformation() { - var sb = new StringBuilder(10240); - var exists = _config.ModDirectory.Length > 0 && Directory.Exists(_config.ModDirectory); - var drive = exists ? new DriveInfo(new DirectoryInfo(_config.ModDirectory).Root.FullName) : null; + var sb = new StringBuilder(10240); + var exists = _config.ModDirectory.Length > 0 && Directory.Exists(_config.ModDirectory); + var hdrEnabler = _services.GetService(); + var drive = exists ? new DriveInfo(new DirectoryInfo(_config.ModDirectory).Root.FullName) : null; sb.AppendLine("**Settings**"); sb.Append($"> **`Plugin Version: `** {_validityChecker.Version}\n"); sb.Append($"> **`Commit Hash: `** {_validityChecker.CommitHash}\n"); @@ -223,9 +225,10 @@ public class Penumbra : IDalamudPlugin sb.Append($"> **`Auto-Deduplication: `** {_config.AutoDeduplicateOnImport}\n"); sb.Append($"> **`Auto-UI-Reduplication: `** {_config.AutoReduplicateUiOnImport}\n"); sb.Append($"> **`Debug Mode: `** {_config.DebugMode}\n"); + sb.Append($"> **`Penumbra Reloads: `** {hdrEnabler.PenumbraReloadCount}\n"); + sb.Append($"> **`HDR Enabled (from Start): `** {_config.HdrRenderTargets} ({hdrEnabler is { FirstLaunchHdrState: true, FirstLaunchHdrHookOverrideState: true }}){(hdrEnabler.HdrEnabledSuccess ? ", Detour Called" : ", **NEVER CALLED**")}\n"); sb.Append($"> **`Hook Overrides: `** {HookOverrides.Instance.IsCustomLoaded}\n"); - sb.Append( - $"> **`Synchronous Load (Dalamud): `** {(_services.GetService().GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n"); + sb.Append($"> **`Synchronous Load (Dalamud): `** {(_services.GetService().GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")} (first Start: {hdrEnabler.FirstLaunchWaitForPluginsState?.ToString() ?? "Unknown"})\n"); sb.Append( $"> **`Logging: `** Log: {_config.Ephemeral.EnableResourceLogging}, Watcher: {_config.Ephemeral.EnableResourceWatcher} ({_config.MaxResourceWatcherRecords})\n"); sb.Append($"> **`Use Ownership: `** {_config.UseOwnerNameForCharacterCollection}\n"); diff --git a/Penumbra/UI/Tabs/Debug/RenderTargetDrawer.cs b/Penumbra/UI/Tabs/Debug/RenderTargetDrawer.cs index 09c8b06c..c8c90e09 100644 --- a/Penumbra/UI/Tabs/Debug/RenderTargetDrawer.cs +++ b/Penumbra/UI/Tabs/Debug/RenderTargetDrawer.cs @@ -4,18 +4,57 @@ using ImGuiNET; using OtterGui; using OtterGui.Services; using OtterGui.Text; +using Penumbra.Interop.Hooks; using Penumbra.Interop.Hooks.PostProcessing; +using Penumbra.Services; namespace Penumbra.UI.Tabs.Debug; -public class RenderTargetDrawer(RenderTargetHdrEnabler renderTargetHdrEnabler) : IUiService +public class RenderTargetDrawer(RenderTargetHdrEnabler renderTargetHdrEnabler, DalamudConfigService dalamudConfig, Configuration config) : IUiService { + private void DrawStatistics() + { + using (ImUtf8.Group()) + { + ImUtf8.Text("Wait For Plugins (Now)"); + ImUtf8.Text("Wait For Plugins (First Launch)"); + + ImUtf8.Text("HDR Enabled (Now)"); + ImUtf8.Text("HDR Enabled (First Launch)"); + + ImUtf8.Text("HDR Hook Overriden (Now)"); + ImUtf8.Text("HDR Hook Overriden (First Launch)"); + + ImUtf8.Text("HDR Detour Called"); + ImUtf8.Text("Penumbra Reload Count"); + } + ImGui.SameLine(); + using (ImUtf8.Group()) + { + ImUtf8.Text($"{(dalamudConfig.GetDalamudConfig(DalamudConfigService.WaitingForPluginsOption, out bool w) ? w.ToString() : "Unknown")}"); + ImUtf8.Text($"{renderTargetHdrEnabler.FirstLaunchWaitForPluginsState?.ToString() ?? "Unknown"}"); + + ImUtf8.Text($"{config.HdrRenderTargets}"); + ImUtf8.Text($"{renderTargetHdrEnabler.FirstLaunchHdrState}"); + + ImUtf8.Text($"{HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize}"); + ImUtf8.Text($"{!renderTargetHdrEnabler.FirstLaunchHdrHookOverrideState}"); + + ImUtf8.Text($"{renderTargetHdrEnabler.HdrEnabledSuccess}"); + ImUtf8.Text($"{renderTargetHdrEnabler.PenumbraReloadCount}"); + } + } + /// Draw information about render targets. public unsafe void Draw() { if (!ImUtf8.CollapsingHeader("Render Targets"u8)) return; + DrawStatistics(); + ImUtf8.Dummy(0); + ImGui.Separator(); + ImUtf8.Dummy(0); var report = renderTargetHdrEnabler.TextureReport; if (report == null) {