/// <summary> /// /// </summary> /// <param name="waitForVSync"></param> public override void SwapBuffers(bool waitForVSync) { D3D.Device device = driver.Device; if (device != null) { int status; // tests coop level to make sure we are ok to render device.CheckCooperativeLevel(out status); if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.Success) { // swap back buffer to the front if (isSwapChain) { swapChain.Present(); } else { device.Present(); } } else if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceLost) { // Device is lost, and is not available for reset now log.Warn("Device State: DeviceLost"); D3D9RenderSystem renderSystem = (D3D9RenderSystem)Root.Instance.RenderSystem; renderSystem.NotifyDeviceLost(); } else if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceNotReset) { // The device needs to be reset, and has not yet been reset. log.Warn("Device State: DeviceNotReset"); device.Reset(device.PresentationParameters); } else { throw new Exception(string.Format("Unknown status code from CheckCooperativeLevel: {0}", status)); } } }
public override void Update() { D3D9RenderSystem rs = (D3D9RenderSystem)Root.Instance.RenderSystem; // access device through driver D3D.Device device = driver.Device; if (rs.DeviceLost) { log.Info("In D3DRenderWindow.Update, rs.DeviceLost is true"); // Test the cooperative mode first int status; device.CheckCooperativeLevel(out status); if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceLost) { // device lost, and we can't reset // can't do anything about it here, wait until we get // D3DERR_DEVICENOTRESET; rendering calls will silently fail until // then (except Present, but we ignore device lost there too) // FIXME: Ogre doesn't do these two Dispose calls here. #if NOT // This code is what Ogre does for this clause, but since // Ogre gets to immediately call release on the renderSurface // and renderZBuffer, this assign of null will end up leaving // the reference count at 0 for them, and will cause them to // be freed. For the Axiom code, I'm just going to leave them // alone, and do the proper dispose calls in the devicenotreset // clause. renderSurface = null; // need to release if swap chain if (!isSwapChain) { renderZBuffer = null; } else { // Do I need to dispose of the ZBuffer here? // SAFE_RELEASE (mpRenderZBuffer); if (renderZBuffer != null) { renderZBuffer.Dispose(); renderZBuffer = null; } } #endif Thread.Sleep(50); return; } else { if (status != (int)Microsoft.DirectX.Direct3D.ResultCode.Success && status != (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceNotReset) { // I've encountered some unexpected device state // Ogre would just continue, but I want to make sure I notice this. throw new Exception(string.Format("Unknown Device State: {0}", status)); } // FIXME: Ogre doesn't do these two Dispose calls here. if (renderSurface != null) { log.Info("Disposing of render surface"); renderSurface.Dispose(); renderSurface = null; } if (renderZBuffer != null) { log.Info("Disposing of render zbuffer"); renderZBuffer.Dispose(); renderZBuffer = null; } log.InfoFormat("In D3DRenderWindow.Update, calling rs.RestoreLostDevice(); status = {0}", status); // device lost, and we can reset rs.RestoreLostDevice(); // Still lost? if (rs.DeviceLost) { // Wait a while Thread.Sleep(50); return; } if (!isSwapChain) { log.Info("In D3DRenderWindow.Update, re-querying buffers"); // re-qeuery buffers renderSurface = device.GetRenderTarget(0); renderZBuffer = device.DepthStencilSurface; // release immediately so we don't hog them // mpRenderSurface->Release(); // mpRenderZBuffer->Release(); } else { log.Info("In D3DRenderWindow.Update, isSwapChain is true, changing viewport dimensions"); // Update dimensions incase changed foreach (Axiom.Core.Viewport vp in viewportList) { vp.UpdateDimensions(); } // Actual restoration of surfaces will happen in // D3D9RenderSystem.RestoreLostDevice when it calls // CreateD3DResources for each secondary window } } } base.Update(); }