d3d display method: survive ctrl+alt+del (should fix #522)

This commit is contained in:
zeromus 2016-04-20 14:29:23 -05:00
parent 3adc8f7c82
commit 1aa4382d21
1 changed files with 50 additions and 21 deletions

View File

@ -80,6 +80,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
{
BackBufferWidth = 8,
BackBufferHeight = 8,
BackBufferCount = 2,
DeviceWindowHandle = OffscreenNativeWindow.WindowInfo.Handle,
PresentationInterval = PresentInterval.Immediate,
EnableAutoDepthStencil = false
@ -88,20 +89,27 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
void ResetDevice()
{
devBB.Dispose();
ResetHandlers.Reset();
for(;;)
for (; ; )
{
var pp = MakePresentParameters();
try
{
dev.Reset(pp);
}
catch { }
if (dev.TestCooperativeLevel().IsSuccess)
var result = dev.TestCooperativeLevel();
if (result.IsSuccess)
break;
if (result.Code == -2005530519) // D3DERR_DEVICENOTRESET
{
try
{
var pp = MakePresentParameters();
dev.Reset(pp);
break;
}
catch { }
}
System.Threading.Thread.Sleep(100);
}
ResetHandlers.Restore();
devBB = dev.GetBackBuffer(0, 0);
}
public void CreateDevice()
@ -118,6 +126,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
flags |= CreateFlags.FpuPreserve;
dev = new Device(d3d, 0, DeviceType.Hardware, pp.DeviceWindowHandle, flags, pp);
devBB = dev.GetBackBuffer(0, 0);
}
void IDisposable.Dispose()
@ -816,19 +825,19 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
public void BeginControl(GLControlWrapper_SlimDX9 control)
{
_CurrentControl = control;
//don't dispose this backbuffer reference, even though it's tempting to.
//it results in weird flashes of corruption when changing the vsync setting (unproven; it's another similar code sequence that broke it)
dev.SetRenderTarget(0, _CurrentControl.SwapChain.GetBackBuffer(0));
}
//this dispose isnt strictly needed but it seems benign
var surface = _CurrentControl.SwapChain.GetBackBuffer(0);
dev.SetRenderTarget(0, surface);
surface.Dispose();
}
Surface devBB;
public void EndControl(GLControlWrapper_SlimDX9 control)
{
if (control != _CurrentControl)
throw new InvalidOperationException();
//don't dispose this backbuffer reference, even though it's tempting to.
//it results in weird flashes of corruption when changing the vsync setting (unproven; it's another similar code sequence that broke it)
dev.SetRenderTarget(0, dev.GetBackBuffer(0, 0));
dev.SetRenderTarget(0, devBB);
_CurrentControl = null;
}
@ -865,6 +874,18 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
var tw = new TextureWrapper() { Texture = d3dtex };
var tex = new Texture2d(this, tw, w, h);
RenderTarget rt = new RenderTarget(this, tw, tex);
ResetHandlers.Add(rt, "RenderTarget",
() =>
{
d3dtex.Dispose();
tw.Texture = null;
},
() =>
{
d3dtex = new d3d9.Texture(dev, w, h, 1, d3d9.Usage.RenderTarget, d3d9.Format.A8R8G8B8, d3d9.Pool.Default);
tw.Texture = d3dtex;
}
);
return rt;
}
@ -874,15 +895,18 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
if (rt == null)
{
//don't dispose this backbuffer reference, even though it's tempting to.
//it results in weird flashes of corruption when changing the vsync setting
dev.SetRenderTarget(0, _CurrentControl.SwapChain.GetBackBuffer(0));
//this dispose is needed for correct device resets, I have no idea why
//don't try caching it either
var surface = _CurrentControl.SwapChain.GetBackBuffer(0);
dev.SetRenderTarget(0, surface);
surface.Dispose();
dev.DepthStencilSurface = null;
return;
}
//dispose doesn't seem necessary for reset here...
var tw = rt.Opaque as TextureWrapper;
//TODO - cache surface level in an RT wrapper
dev.SetRenderTarget(0, tw.Texture.GetSurfaceLevel(0));
dev.DepthStencilSurface = null;
}
@ -900,7 +924,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
{
BackBufferWidth = Math.Max(8,control.ClientSize.Width),
BackBufferHeight = Math.Max(8, control.ClientSize.Height),
BackBufferCount = 2,
BackBufferCount = 1,
BackBufferFormat = Format.X8R8G8B8,
DeviceWindowHandle = control.Handle,
Windowed = true,
@ -908,7 +932,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
};
control.SwapChain = new SwapChain(dev, pp);
ResetHandlers.Add(control, "SwapChain", () => { control.SwapChain.Dispose(); control.SwapChain = null; }, () => RefreshControlSwapChain(control));
ResetHandlers.Add(control, "SwapChain", () =>
{
control.SwapChain.Dispose();
control.SwapChain = null;
},
() => RefreshControlSwapChain(control));
}
DeviceLostHandler ResetHandlers = new DeviceLostHandler();