diff --git a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
index 0bc05ee39..32e297337 100644
--- a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
+++ b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
using System.Runtime.InteropServices;
using Dalamud.Game.Internal.DXGI.Definitions;
@@ -26,6 +28,11 @@ namespace Dalamud.Game.Internal.DXGI
///
public IntPtr ResizeBuffers { get; set; }
+ ///
+ /// Gets a value indicating whether or not ReShade is loaded/used.
+ ///
+ public bool IsReshade { get; private set; }
+
///
protected override unsafe void Setup64Bit(SigScanner sig)
{
@@ -34,6 +41,32 @@ namespace Dalamud.Game.Internal.DXGI
var scVtbl = GetVTblAddresses(new IntPtr(kernelDev->SwapChain->DXGISwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present];
+
+ var modules = Process.GetCurrentProcess().Modules;
+ foreach (ProcessModule processModule in modules)
+ {
+ if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll"))
+ {
+ // reshade master@4232872 RVA
+ // var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present
+ // var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present
+
+ var scanner = new SigScanner(processModule);
+ try
+ {
+ var p = scanner.ScanText("F6 C2 01 0F 85 ?? ?? ?? ??");
+ Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}");
+
+ this.Present = p;
+ this.IsReshade = true;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!");
+ }
+ }
+ }
+
this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers];
}
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index eb76e05ac..0f218f4e5 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -320,6 +320,10 @@ namespace Dalamud.Interface.Internal
Util.Fatal($"One or more files required by XIVLauncher were not found.\nPlease restart and report this error if it occurs again.\n\n{path}", "Error");
}
+ /*
+ * NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg.
+ * Seems to work fine regardless, I guess, so whatever.
+ */
private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags)
{
if (this.scene != null && swapChain != this.scene.SwapChain.NativePointer)
@@ -398,6 +402,22 @@ namespace Dalamud.Interface.Internal
Service.Get().Enable();
}
+ if (this.address.IsReshade)
+ {
+ var pRes = this.presentHook.Original(swapChain, syncInterval, presentFlags);
+
+ this.RenderImGui();
+
+ return pRes;
+ }
+
+ this.RenderImGui();
+
+ return this.presentHook.Original(swapChain, syncInterval, presentFlags);
+ }
+
+ private void RenderImGui()
+ {
// Process information needed by ImGuiHelpers each frame.
ImGuiHelpers.NewFrame();
@@ -405,8 +425,6 @@ namespace Dalamud.Interface.Internal
this.CheckViewportState();
this.scene.Render();
-
- return this.presentHook.Original(swapChain, syncInterval, presentFlags);
}
private void CheckViewportState()