d3d display method: do a better job of surviving device resets
This commit is contained in:
parent
1ee56ea4ef
commit
1e07625d1d
|
@ -7,13 +7,17 @@ namespace BizHawk.Client.Common
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This singleton class manages OpenGL contexts, in an effort to minimize context changes.
|
/// This singleton class manages OpenGL contexts, in an effort to minimize context changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GLManager
|
public class GLManager : IDisposable
|
||||||
{
|
{
|
||||||
private GLManager()
|
private GLManager()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public static GLManager Instance { get; private set; }
|
public static GLManager Instance { get; private set; }
|
||||||
|
|
||||||
public static void CreateInstance()
|
public static void CreateInstance()
|
||||||
|
|
|
@ -220,7 +220,17 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//cleanup:
|
||||||
|
//cleanup IGL stuff so we can get better refcounts when exiting process, for debugging
|
||||||
|
//DOESNT WORK FOR SOME REASON
|
||||||
|
//GlobalWin.IGL_GL = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK();
|
||||||
|
//GLManager.Instance.Dispose();
|
||||||
|
//if (GlobalWin.IGL_GL != GlobalWin.GL)
|
||||||
|
// GlobalWin.GL.Dispose();
|
||||||
|
//((IDisposable)GlobalWin.IGL_GL).Dispose();
|
||||||
|
|
||||||
|
} //SubMain
|
||||||
|
|
||||||
//declared here instead of a more usual place to avoid dependencies on the more usual place
|
//declared here instead of a more usual place to avoid dependencies on the more usual place
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
|
|
|
@ -62,18 +62,41 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PresentParameters MakePresentParameters()
|
||||||
|
{
|
||||||
|
return new PresentParameters
|
||||||
|
{
|
||||||
|
BackBufferWidth = 8,
|
||||||
|
BackBufferHeight = 8,
|
||||||
|
DeviceWindowHandle = OffscreenNativeWindow.WindowInfo.Handle,
|
||||||
|
PresentationInterval = PresentInterval.Immediate,
|
||||||
|
EnableAutoDepthStencil = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetDevice()
|
||||||
|
{
|
||||||
|
ResetHandlers.Reset();
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
var pp = MakePresentParameters();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dev.Reset(pp);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
if (dev.TestCooperativeLevel().IsSuccess)
|
||||||
|
break;
|
||||||
|
System.Threading.Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
ResetHandlers.Restore();
|
||||||
|
}
|
||||||
|
|
||||||
public void CreateDevice()
|
public void CreateDevice()
|
||||||
{
|
{
|
||||||
DestroyDevice();
|
DestroyDevice();
|
||||||
|
|
||||||
//just create some present params so we can get the device created
|
var pp = MakePresentParameters();
|
||||||
var pp = new PresentParameters
|
|
||||||
{
|
|
||||||
BackBufferWidth = 8,
|
|
||||||
BackBufferHeight = 8,
|
|
||||||
DeviceWindowHandle = OffscreenNativeWindow.WindowInfo.Handle,
|
|
||||||
PresentationInterval = PresentInterval.Immediate
|
|
||||||
};
|
|
||||||
|
|
||||||
var flags = CreateFlags.SoftwareVertexProcessing;
|
var flags = CreateFlags.SoftwareVertexProcessing;
|
||||||
if ((d3d.GetDeviceCaps(0, DeviceType.Hardware).DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
|
if ((d3d.GetDeviceCaps(0, DeviceType.Hardware).DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
|
||||||
|
@ -85,6 +108,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
|
ResetHandlers.Reset();
|
||||||
|
DestroyDevice();
|
||||||
|
d3d.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear(OpenTK.Graphics.OpenGL.ClearBufferMask mask)
|
public void Clear(OpenTK.Graphics.OpenGL.ClearBufferMask mask)
|
||||||
|
@ -737,7 +763,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
public void BeginControl(GLControlWrapper_SlimDX9 control)
|
public void BeginControl(GLControlWrapper_SlimDX9 control)
|
||||||
{
|
{
|
||||||
_CurrentControl = control;
|
_CurrentControl = control;
|
||||||
dev.SetRenderTarget(0, control.SwapChain.GetBackBuffer(0));
|
var bb = control.SwapChain.GetBackBuffer(0);
|
||||||
|
dev.SetRenderTarget(0, bb);
|
||||||
|
bb.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndControl(GLControlWrapper_SlimDX9 control)
|
public void EndControl(GLControlWrapper_SlimDX9 control)
|
||||||
|
@ -745,13 +773,28 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
if (control != _CurrentControl)
|
if (control != _CurrentControl)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
|
var bb = dev.GetBackBuffer(0,0);
|
||||||
|
dev.SetRenderTarget(0,bb);
|
||||||
|
bb.Dispose();
|
||||||
|
|
||||||
_CurrentControl = null;
|
_CurrentControl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwapControl(GLControlWrapper_SlimDX9 control)
|
public void SwapControl(GLControlWrapper_SlimDX9 control)
|
||||||
{
|
{
|
||||||
control.SwapChain.Present(Present.None);
|
EndControl(control);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = control.SwapChain.Present(Present.None);
|
||||||
|
}
|
||||||
|
catch(d3d9.Direct3D9Exception ex)
|
||||||
|
{
|
||||||
|
if (ex.ResultCode.Name == "D3DERR_DEVICELOST")
|
||||||
|
ResetDevice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void FreeRenderTarget(RenderTarget rt)
|
public void FreeRenderTarget(RenderTarget rt)
|
||||||
{
|
{
|
||||||
|
@ -777,7 +820,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
|
|
||||||
if (rt == null)
|
if (rt == null)
|
||||||
{
|
{
|
||||||
dev.SetRenderTarget(0, _CurrentControl.SwapChain.GetBackBuffer(0));
|
var bb = _CurrentControl.SwapChain.GetBackBuffer(0);
|
||||||
|
dev.SetRenderTarget(0, bb);
|
||||||
|
bb.Dispose();
|
||||||
dev.DepthStencilSurface = null;
|
dev.DepthStencilSurface = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -795,6 +840,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
control.SwapChain.Dispose();
|
control.SwapChain.Dispose();
|
||||||
control.SwapChain = null;
|
control.SwapChain = null;
|
||||||
}
|
}
|
||||||
|
ResetHandlers.Remove(control, "SwapChain");
|
||||||
|
|
||||||
var pp = new PresentParameters
|
var pp = new PresentParameters
|
||||||
{
|
{
|
||||||
|
@ -808,8 +854,66 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
||||||
};
|
};
|
||||||
|
|
||||||
control.SwapChain = new SwapChain(dev, pp);
|
control.SwapChain = new SwapChain(dev, pp);
|
||||||
|
ResetHandlers.Add(control, "SwapChain", () => { control.SwapChain.Dispose(); control.SwapChain = null; }, () => RefreshControlSwapChain(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceLostHandler ResetHandlers = new DeviceLostHandler();
|
||||||
|
|
||||||
|
class DeviceLostHandler
|
||||||
|
{
|
||||||
|
class ResetHandlerKey
|
||||||
|
{
|
||||||
|
public string Label;
|
||||||
|
public object Object;
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Label.GetHashCode() ^ Object.GetHashCode();
|
||||||
|
}
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj == null) return false;
|
||||||
|
var key = obj as ResetHandlerKey;
|
||||||
|
return key.Label == Label && key.Object == Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HandlerSet
|
||||||
|
{
|
||||||
|
public Action Reset, Restore;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<ResetHandlerKey, HandlerSet> Handlers = new Dictionary<ResetHandlerKey, HandlerSet>();
|
||||||
|
|
||||||
|
public void Add(object o, string label, Action reset, Action restore)
|
||||||
|
{
|
||||||
|
ResetHandlerKey hkey = new ResetHandlerKey() { Object = o, Label = label };
|
||||||
|
Handlers[hkey] = new HandlerSet { Reset = reset, Restore = restore };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(object o, string label)
|
||||||
|
{
|
||||||
|
ResetHandlerKey hkey = new ResetHandlerKey() { Object = o, Label = label };
|
||||||
|
if(Handlers.ContainsKey(hkey))
|
||||||
|
Handlers.Remove(hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
foreach (var handler in Handlers)
|
||||||
|
handler.Value.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore()
|
||||||
|
{
|
||||||
|
var todo = Handlers.ToArray();
|
||||||
|
Handlers.Clear();
|
||||||
|
foreach (var item in todo)
|
||||||
|
item.Value.Restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public IGraphicsControl Internal_CreateGraphicsControl()
|
public IGraphicsControl Internal_CreateGraphicsControl()
|
||||||
{
|
{
|
||||||
var ret = new GLControlWrapper_SlimDX9(this);
|
var ret = new GLControlWrapper_SlimDX9(this);
|
||||||
|
|
Loading…
Reference in New Issue