bool D3D9Device::validateDeviceState(const D3D9RenderWindowCore* renderWindow) { RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow); RenderWindowResources* renderWindowResources = it->second; HRESULT hr; hr = mpDevice->TestCooperativeLevel(); // Case device is not valid for rendering. if (FAILED(hr)) { // 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) if (hr == D3DERR_DEVICELOST) { releaseRenderWindowResources(renderWindowResources); notifyDeviceLost(); return false; } // device lost, and we can reset else if (hr == D3DERR_DEVICENOTRESET) { bool deviceRestored = reset(); // Device was not restored yet. if (deviceRestored == false) { // Wait a while Sleep(50); return false; } } } // Render window resources explicitly invalidated. (Resize or window mode switch) if (renderWindowResources->acquired == false) { if (getPrimaryWindow() == renderWindow) { bool deviceRestored = reset(); // Device was not restored yet. if (deviceRestored == false) { // Wait a while Sleep(50); return false; } } else { acquire(renderWindow); } } return true; }
bool Display::testDeviceLost() { ASSERT(isInitialized()); if (!mDeviceLost && mImplementation->testDeviceLost()) { notifyDeviceLost(); } return mDeviceLost; }
gl::GraphicsResetStatus RendererD3D::getResetStatus() { if (!mDeviceLost) { if (testDeviceLost()) { mDeviceLost = true; notifyDeviceLost(); return gl::GraphicsResetStatus::UnknownContextReset; } return gl::GraphicsResetStatus::NoError; } if (testDeviceResettable()) { return gl::GraphicsResetStatus::NoError; } return gl::GraphicsResetStatus::UnknownContextReset; }
GLenum RendererD3D::getResetStatus() { if (!mDeviceLost) { if (testDeviceLost()) { mDeviceLost = true; notifyDeviceLost(); return GL_UNKNOWN_CONTEXT_RESET_EXT; } return GL_NO_ERROR; } if (testDeviceResettable()) { return GL_NO_ERROR; } return GL_UNKNOWN_CONTEXT_RESET_EXT; }
void Display::sync(bool block) { HRESULT result; IDirect3DQuery9* query = allocateEventQuery(); if (!query) { return; } result = query->Issue(D3DISSUE_END); ASSERT(SUCCEEDED(result)); do { result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); if(block && result == S_FALSE) { // Keep polling, but allow other threads to do something useful first Sleep(0); // explicitly check for device loss // some drivers seem to return S_FALSE even if the device is lost // instead of D3DERR_DEVICELOST like they should if (testDeviceLost()) { result = D3DERR_DEVICELOST; } } } while(block && result == S_FALSE); freeEventQuery(query); if (isDeviceLostError(result)) { notifyDeviceLost(); } }
void D3D9Device::present(const D3D9RenderWindowCore* renderWindow) { RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow); RenderWindowResources* renderWindowResources = it->second; // Skip present while current device state is invalid. if (mDeviceLost || renderWindowResources->acquired == false || isDeviceLost()) return; HRESULT hr; if (isMultihead()) { // Only the master will call present method results in synchronized // buffer swap for the rest of the implicit swap chain. if (getPrimaryWindow() == renderWindow) hr = mpDevice->Present( NULL, NULL, NULL, NULL ); else hr = S_OK; } else { hr = renderWindowResources->swapChain->Present(NULL, NULL, NULL, NULL, 0); } if(D3DERR_DEVICELOST == hr) { releaseRenderWindowResources(renderWindowResources); notifyDeviceLost(); } else if( FAILED(hr) ) { BS_EXCEPT(RenderingAPIException, "Error Presenting surfaces"); } }