Avoid hard depending on Direct3D 11.1, slighly optimize presentation
This commit is contained in:
parent
bfec776bd7
commit
1260ecd01a
|
@ -48,10 +48,12 @@ namespace BizHawk.Bizware.Graphics.Controls
|
||||||
=> Vsync = state;
|
=> Vsync = state;
|
||||||
|
|
||||||
public override void Begin()
|
public override void Begin()
|
||||||
=> _swapChain.SetBackBuffer();
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void End()
|
public override void End()
|
||||||
=> _swapChain.SetBackBuffer();
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override void SwapBuffers()
|
public override void SwapBuffers()
|
||||||
=> _swapChain.PresentBuffer(ControlParameters);
|
=> _swapChain.PresentBuffer(ControlParameters);
|
||||||
|
|
|
@ -16,7 +16,8 @@ namespace BizHawk.Bizware.Graphics.Controls
|
||||||
public abstract void SetVsync(bool state);
|
public abstract void SetVsync(bool state);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Swaps the buffers for this control
|
/// Swaps the buffers for this control.
|
||||||
|
/// Be aware, the owner IGL's current render target is undefined after calling this
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void SwapBuffers();
|
public abstract void SwapBuffers();
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,10 @@ namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
public ID3D11Device Device;
|
public ID3D11Device Device;
|
||||||
public ID3D11DeviceContext Context;
|
public ID3D11DeviceContext Context;
|
||||||
|
public ID3D11DeviceContext1 Context1;
|
||||||
public ID3D11Texture2D BackBufferTexture;
|
public ID3D11Texture2D BackBufferTexture;
|
||||||
public ID3D11RenderTargetView RTV;
|
public ID3D11RenderTargetView RTV;
|
||||||
public IDXGISwapChain1 SwapChain;
|
public IDXGISwapChain SwapChain;
|
||||||
public bool AllowsTearing;
|
public bool AllowsTearing;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -41,6 +42,8 @@ namespace BizHawk.Bizware.Graphics
|
||||||
// Device/Context not owned by this class
|
// Device/Context not owned by this class
|
||||||
Device = null;
|
Device = null;
|
||||||
Context = null;
|
Context = null;
|
||||||
|
Context1?.Dispose();
|
||||||
|
Context1 = null;
|
||||||
RTV?.Dispose();
|
RTV?.Dispose();
|
||||||
RTV = null;
|
RTV = null;
|
||||||
BackBufferTexture?.Dispose();
|
BackBufferTexture?.Dispose();
|
||||||
|
@ -57,9 +60,10 @@ namespace BizHawk.Bizware.Graphics
|
||||||
|
|
||||||
private ID3D11Device Device => _resources.Device;
|
private ID3D11Device Device => _resources.Device;
|
||||||
private ID3D11DeviceContext Context => _resources.Context;
|
private ID3D11DeviceContext Context => _resources.Context;
|
||||||
|
private ID3D11DeviceContext1 Context1 => _resources.Context1;
|
||||||
private ID3D11Texture2D BackBufferTexture => _resources.BackBufferTexture;
|
private ID3D11Texture2D BackBufferTexture => _resources.BackBufferTexture;
|
||||||
private ID3D11RenderTargetView RTV => _resources.RTV;
|
private ID3D11RenderTargetView RTV => _resources.RTV;
|
||||||
private IDXGISwapChain1 SwapChain => _resources.SwapChain;
|
private IDXGISwapChain SwapChain => _resources.SwapChain;
|
||||||
private bool AllowsTearing => _resources.AllowsTearing;
|
private bool AllowsTearing => _resources.AllowsTearing;
|
||||||
|
|
||||||
internal D3D11SwapChain(SwapChainResources resources, Action<ControlParameters> resetDeviceCallback)
|
internal D3D11SwapChain(SwapChainResources resources, Action<ControlParameters> resetDeviceCallback)
|
||||||
|
@ -71,12 +75,9 @@ namespace BizHawk.Bizware.Graphics
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
=> _resources.Dispose();
|
=> _resources.Dispose();
|
||||||
|
|
||||||
public void SetBackBuffer()
|
|
||||||
=> Context.OMSetRenderTargets(RTV);
|
|
||||||
|
|
||||||
public void PresentBuffer(ControlParameters cp)
|
public void PresentBuffer(ControlParameters cp)
|
||||||
{
|
{
|
||||||
SetBackBuffer();
|
Context.OMSetRenderTargets(RTV);
|
||||||
|
|
||||||
PresentFlags presentFlags;
|
PresentFlags presentFlags;
|
||||||
if (cp.Vsync)
|
if (cp.Vsync)
|
||||||
|
@ -95,6 +96,9 @@ namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
_resetDeviceCallback(cp);
|
_resetDeviceCallback(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimization hint to the GPU (note: not always available, needs Win8+ or Win7 with the Platform Update)
|
||||||
|
Context1?.DiscardView(RTV);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Refresh(ControlParameters cp)
|
public void Refresh(ControlParameters cp)
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace BizHawk.Bizware.Graphics
|
||||||
|
|
||||||
private struct D3D11Resources : IDisposable
|
private struct D3D11Resources : IDisposable
|
||||||
{
|
{
|
||||||
public IDXGIFactory2 Factory;
|
public IDXGIFactory1 Factory1;
|
||||||
|
public IDXGIFactory2 Factory2;
|
||||||
public ID3D11Device Device;
|
public ID3D11Device Device;
|
||||||
public ID3D11DeviceContext Context;
|
public ID3D11DeviceContext Context;
|
||||||
public ID3D11BlendState BlendEnableState;
|
public ID3D11BlendState BlendEnableState;
|
||||||
|
@ -40,8 +41,10 @@ namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// we need IDXGIFactory2 for CreateSwapChainForHwnd
|
Factory1 = DXGI.CreateDXGIFactory1<IDXGIFactory1>();
|
||||||
Factory = DXGI.CreateDXGIFactory1<IDXGIFactory2>();
|
// we want IDXGIFactory2 for CreateSwapChainForHwnd
|
||||||
|
// however, it's not guaranteed to be available (only available in Win8+ or Win7 with the Platform Update)
|
||||||
|
Factory2 = Factory1.QueryInterfaceOrNull<IDXGIFactory2>();
|
||||||
#if false
|
#if false
|
||||||
// use this to debug D3D11 calls
|
// use this to debug D3D11 calls
|
||||||
// note debug layer requires extra steps to use: https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-layers#debug-layer
|
// note debug layer requires extra steps to use: https://learn.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-layers#debug-layer
|
||||||
|
@ -124,8 +127,11 @@ namespace BizHawk.Bizware.Graphics
|
||||||
Device?.Dispose();
|
Device?.Dispose();
|
||||||
Device = null;
|
Device = null;
|
||||||
|
|
||||||
Factory?.Dispose();
|
Factory2?.Dispose();
|
||||||
Factory = null;
|
Factory2 = null;
|
||||||
|
|
||||||
|
Factory1?.Dispose();
|
||||||
|
Factory1 = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +139,8 @@ namespace BizHawk.Bizware.Graphics
|
||||||
// these might need to be thrown out and recreated if the device is lost
|
// these might need to be thrown out and recreated if the device is lost
|
||||||
private D3D11Resources _resources;
|
private D3D11Resources _resources;
|
||||||
|
|
||||||
private IDXGIFactory2 Factory => _resources.Factory;
|
private IDXGIFactory1 Factory1 => _resources.Factory1;
|
||||||
|
private IDXGIFactory2 Factory2 => _resources.Factory2;
|
||||||
private ID3D11Device Device => _resources.Device;
|
private ID3D11Device Device => _resources.Device;
|
||||||
private ID3D11DeviceContext Context => _resources.Context;
|
private ID3D11DeviceContext Context => _resources.Context;
|
||||||
private ID3D11BlendState BlendEnableState => _resources.BlendEnableState;
|
private ID3D11BlendState BlendEnableState => _resources.BlendEnableState;
|
||||||
|
@ -166,7 +173,31 @@ namespace BizHawk.Bizware.Graphics
|
||||||
_resources.CreateResources();
|
_resources.CreateResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IDXGISwapChain1 CreateDXGISwapChain(D3D11SwapChain.ControlParameters cp)
|
private IDXGISwapChain CreateDXGISwapChain(D3D11SwapChain.ControlParameters cp)
|
||||||
|
{
|
||||||
|
IDXGISwapChain ret;
|
||||||
|
|
||||||
|
if (Factory2 is null)
|
||||||
|
{
|
||||||
|
// no Factory2, probably on Windows 7 without the Platform Update
|
||||||
|
// we can assume a simple legacy format is needed here
|
||||||
|
var sd = default(SwapChainDescription);
|
||||||
|
sd.BufferDescription = new(
|
||||||
|
width: cp.Width,
|
||||||
|
height: cp.Height,
|
||||||
|
refreshRate: new(0, 0),
|
||||||
|
format: Format.B8G8R8A8_UNorm);
|
||||||
|
sd.SampleDescription = SampleDescription.Default;
|
||||||
|
sd.BufferUsage = Usage.RenderTargetOutput;
|
||||||
|
sd.BufferCount = 2;
|
||||||
|
sd.OutputWindow = cp.Handle;
|
||||||
|
sd.Windowed = true;
|
||||||
|
sd.SwapEffect = SwapEffect.Discard;
|
||||||
|
sd.Flags = SwapChainFlags.None;
|
||||||
|
|
||||||
|
ret = Factory1.CreateSwapChain(Device, sd);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// this is the optimal swapchain model
|
// this is the optimal swapchain model
|
||||||
// note however it requires windows 10+
|
// note however it requires windows 10+
|
||||||
|
@ -183,20 +214,20 @@ namespace BizHawk.Bizware.Graphics
|
||||||
alphaMode: AlphaMode.Ignore,
|
alphaMode: AlphaMode.Ignore,
|
||||||
flags: SwapChainFlags.AllowTearing);
|
flags: SwapChainFlags.AllowTearing);
|
||||||
|
|
||||||
IDXGISwapChain1 ret;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ret = Factory.CreateSwapChainForHwnd(Device, cp.Handle, sd);
|
ret = Factory2.CreateSwapChainForHwnd(Device, cp.Handle, sd);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
sd.SwapEffect = SwapEffect.Discard;
|
sd.SwapEffect = SwapEffect.Discard;
|
||||||
sd.Flags = SwapChainFlags.None;
|
sd.Flags = SwapChainFlags.None;
|
||||||
ret = Factory.CreateSwapChainForHwnd(Device, cp.Handle, sd);
|
ret = Factory2.CreateSwapChainForHwnd(Device, cp.Handle, sd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't allow DXGI to snoop alt+enter and such
|
// don't allow DXGI to snoop alt+enter and such
|
||||||
using var parentFactory = ret.GetParent<IDXGIFactory2>();
|
using var parentFactory = ret.GetParent<IDXGIFactory>();
|
||||||
parentFactory.MakeWindowAssociation(cp.Handle, WindowAssociationFlags.IgnoreAll);
|
parentFactory.MakeWindowAssociation(cp.Handle, WindowAssociationFlags.IgnoreAll);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -330,10 +361,11 @@ namespace BizHawk.Bizware.Graphics
|
||||||
|
|
||||||
_controlSwapChain.Device = Device;
|
_controlSwapChain.Device = Device;
|
||||||
_controlSwapChain.Context = Context;
|
_controlSwapChain.Context = Context;
|
||||||
|
_controlSwapChain.Context1 = Context.QueryInterfaceOrNull<ID3D11DeviceContext1>();
|
||||||
_controlSwapChain.BackBufferTexture = bbTex;
|
_controlSwapChain.BackBufferTexture = bbTex;
|
||||||
_controlSwapChain.RTV = rtv;
|
_controlSwapChain.RTV = rtv;
|
||||||
_controlSwapChain.SwapChain = swapChain;
|
_controlSwapChain.SwapChain = swapChain;
|
||||||
_controlSwapChain.AllowsTearing = (swapChain.Description1.Flags & SwapChainFlags.AllowTearing) != 0;
|
_controlSwapChain.AllowsTearing = (swapChain.Description.Flags & SwapChainFlags.AllowTearing) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public D3D11SwapChain CreateSwapChain(D3D11SwapChain.ControlParameters cp)
|
public D3D11SwapChain CreateSwapChain(D3D11SwapChain.ControlParameters cp)
|
||||||
|
@ -348,14 +380,15 @@ namespace BizHawk.Bizware.Graphics
|
||||||
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
|
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
|
||||||
var rtv = Device.CreateRenderTargetView(bbTex, rtvd);
|
var rtv = Device.CreateRenderTargetView(bbTex, rtvd);
|
||||||
|
|
||||||
_controlSwapChain = new D3D11SwapChain.SwapChainResources
|
_controlSwapChain = new()
|
||||||
{
|
{
|
||||||
Device = Device,
|
Device = Device,
|
||||||
Context = Context,
|
Context = Context,
|
||||||
|
Context1 = Context.QueryInterfaceOrNull<ID3D11DeviceContext1>(),
|
||||||
BackBufferTexture = bbTex,
|
BackBufferTexture = bbTex,
|
||||||
RTV = rtv,
|
RTV = rtv,
|
||||||
SwapChain = swapChain,
|
SwapChain = swapChain,
|
||||||
AllowsTearing = (swapChain.Description1.Flags & SwapChainFlags.AllowTearing) != 0,
|
AllowsTearing = (swapChain.Description.Flags & SwapChainFlags.AllowTearing) != 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
return new(_controlSwapChain, ResetDevice);
|
return new(_controlSwapChain, ResetDevice);
|
||||||
|
|
Loading…
Reference in New Issue