feat: use game KernelDevice to get DXGI SwapChain

This commit is contained in:
goat 2021-09-15 01:43:18 +02:00
parent b9d8a2f207
commit 31d8d45c72
No known key found for this signature in database
GPG key ID: F18F057873895461

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Dalamud.Game.Internal.DXGI.Definitions; using Dalamud.Game.Internal.DXGI.Definitions;
using Serilog;
using SharpDX.Direct3D; using SharpDX.Direct3D;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SharpDX.DXGI; using SharpDX.DXGI;
@ -19,9 +20,6 @@ namespace Dalamud.Game.Internal.DXGI
/// </remarks> /// </remarks>
public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver
{ {
private List<IntPtr> d3d11VTblAddresses;
private List<IntPtr> dxgiSwapChainVTblAddresses;
/// <inheritdoc/> /// <inheritdoc/>
public IntPtr Present { get; set; } public IntPtr Present { get; set; }
@ -29,50 +27,14 @@ namespace Dalamud.Game.Internal.DXGI
public IntPtr ResizeBuffers { get; set; } public IntPtr ResizeBuffers { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Setup64Bit(SigScanner sig) protected override unsafe void Setup64Bit(SigScanner sig)
{ {
// Create temporary device + swapchain and determine method addresses var kernelDev = FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Device.Instance();
if (this.d3d11VTblAddresses == null)
{
// A renderable object isnt required, just a handle
var handle = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>());
Device.CreateWithSwapChain( var scVtbl = GetVTblAddresses(new IntPtr(kernelDev->SwapChain->DXGISwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
DriverType.Hardware,
DeviceCreationFlags.BgraSupport,
CreateSwapChainDescription(handle),
out var device,
out var swapChain);
if (device != null && swapChain != null) this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present];
{ this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers];
this.d3d11VTblAddresses = GetVTblAddresses(device.NativePointer, Enum.GetValues(typeof(ID3D11DeviceVtbl)).Length);
this.dxgiSwapChainVTblAddresses = GetVTblAddresses(swapChain.NativePointer, Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length);
}
device?.Dispose();
swapChain?.Dispose();
Marshal.FreeHGlobal(handle);
}
this.Present = this.dxgiSwapChainVTblAddresses[(int)IDXGISwapChainVtbl.Present];
this.ResizeBuffers = this.dxgiSwapChainVTblAddresses[(int)IDXGISwapChainVtbl.ResizeBuffers];
}
private static SwapChainDescription CreateSwapChainDescription(IntPtr renderForm)
{
return new SwapChainDescription
{
BufferCount = 1,
Flags = SwapChainFlags.None,
IsWindowed = true,
ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), Format.R8G8B8A8_UNorm),
OutputHandle = renderForm,
SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput,
};
} }
private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods) private static List<IntPtr> GetVTblAddresses(IntPtr pointer, int numberOfMethods)