From 661e79aa2fde7b592b6077a29e58308096febf25 Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sat, 28 Dec 2019 18:24:54 -0800 Subject: [PATCH] WIP updates for direct render testing. Currently ImGui draws, but basically off into space and nothing is visible. Working on porting some reshade logic to see if we can get away with simple additional targets and msaa handling --- Dalamud/Dalamud.cs | 4 +- .../Internal/DXGI/SwapChainAddressResolver.cs | 22 ++++ Dalamud/Interface/InterfaceManager.cs | 109 +++++++++++++----- lib/ImGuiScene | 2 +- 4 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 Dalamud/Game/Internal/DXGI/SwapChainAddressResolver.cs diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 17cbbba04..6b55429b2 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -84,8 +84,8 @@ namespace Dalamud { this.WinSock2 = new WinSockHandlers(); - this.InterfaceManager = new InterfaceManager(); - this.InterfaceManager.Start(); + this.InterfaceManager = new InterfaceManager(this, this.sigScanner); + //this.InterfaceManager.Start(); try { this.PluginManager.LoadPlugins(); diff --git a/Dalamud/Game/Internal/DXGI/SwapChainAddressResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainAddressResolver.cs new file mode 100644 index 000000000..7ddb2ff37 --- /dev/null +++ b/Dalamud/Game/Internal/DXGI/SwapChainAddressResolver.cs @@ -0,0 +1,22 @@ +using System; +using System.Diagnostics; +using System.Linq; +using Serilog; + +namespace Dalamud.Game.Internal.DXGI +{ + public sealed class SwapChainAddressResolver : BaseAddressResolver + { + public IntPtr Present { get; private set; } + + protected override void Setup64Bit(SigScanner sig) + { + var module = Process.GetCurrentProcess().Modules.Cast().First(m => m.ModuleName == "dxgi.dll"); + + Log.Debug($"Found DXGI: {module.BaseAddress.ToInt64():X}"); + + var scanner = new SigScanner(module); + Present = scanner.ScanModule("48 89 5C 24 ?? 48 89 74 24 ?? 55 57 41 56 48 8D 6C 24 ??"); + } + } +} diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index 4759002ec..50d0cf362 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -1,51 +1,108 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using Dalamud.Game; +using Dalamud.Game.Internal.DXGI; +using Dalamud.Hooking; using ImGuiNET; using ImGuiScene; +using Serilog; namespace Dalamud.Interface { public class InterfaceManager : IDisposable { - private Task _task; + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + private delegate IntPtr PresentDelegate(IntPtr swapChain, uint syncInterval, uint presentFlags); + + private readonly Hook presentHook; + + private SwapChainAddressResolver Address { get; } + + + //private Task _task; + private RawDX11Scene _scene; + private Dalamud _dalamud; + + public InterfaceManager(Dalamud dalamud, SigScanner scanner) + { + this._dalamud = dalamud; + + Address = new SwapChainAddressResolver(); + Address.Setup(scanner); + + Log.Verbose("===== S W A P C H A I N ====="); + Log.Verbose("Present address {Present}", Address.Present); + + this.presentHook = + new Hook(Address.Present, + new PresentDelegate(PresentDetour), + this); + Enable(); + } + + public void Enable() + { + this.presentHook.Enable(); + } + + public void Disable() + { + this.presentHook.Disable(); + } public void Dispose() { - _task?.Wait(); - _task = null; + this._scene.Dispose(); + this.presentHook.Dispose(); + + //_task?.Wait(); + //_task = null; } - public void Start() + //public void Start() + //{ + // if (_task == null || _task.IsCompleted || _task.IsFaulted || _task.IsCanceled) + // { + // _task = new Task(Display); + // _task.Start(); + // } + //} + + //private void Display() + //{ + // using (var scene = SimpleImGuiScene.CreateOverlay(RendererFactory.RendererBackend.DirectX11)) + // { + // // this basically pauses background rendering to reduce cpu load by the scene when it isn't actively in focus + // // the impact is generally pretty minor, but it's probably best to enable when we can + // // If we have any windows that we want to update dynamically even when the game is the focus + // // and not the overlay, this should be disabled. + // // It is dynamic, so we could disable it only when dynamic windows are open etc + // scene.PauseWhenUnfocused = true; + + // scene.OnBuildUI += DrawUI; + // scene.Run(); + // } + //} + + //private void DrawUI() + //{ + // ImGui.ShowDemoWindow(); + //} + + private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags) { - if (_task == null || _task.IsCompleted || _task.IsFaulted || _task.IsCanceled) + if (_scene == null) { - _task = new Task(Display); - _task.Start(); + _scene = new RawDX11Scene(swapChain); } - } - private void Display() - { - using (var scene = SimpleImGuiScene.CreateOverlay(RendererFactory.RendererBackend.DirectX11)) - { - // this basically pauses background rendering to reduce cpu load by the scene when it isn't actively in focus - // the impact is generally pretty minor, but it's probably best to enable when we can - // If we have any windows that we want to update dynamically even when the game is the focus - // and not the overlay, this should be disabled. - // It is dynamic, so we could disable it only when dynamic windows are open etc - scene.PauseWhenUnfocused = true; + _scene.Render(); - scene.OnBuildUI += DrawUI; - scene.Run(); - } - } - - private void DrawUI() - { - ImGui.ShowDemoWindow(); + return this.presentHook.Original(swapChain, syncInterval, presentFlags); } } } diff --git a/lib/ImGuiScene b/lib/ImGuiScene index d0f143197..82b3509a4 160000 --- a/lib/ImGuiScene +++ b/lib/ImGuiScene @@ -1 +1 @@ -Subproject commit d0f143197f4620150cadf1020c45bfaf856e7801 +Subproject commit 82b3509a40d5311afbd0ecf0e9494ccf43c554ff