Add handling for certain cases of D3D9Ex device lost.

This will allow us to handle TDR restarts on newer machines. We still don't handle D3DERR_DEVICEREMOVED.

TRAC #22492

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1927 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 4552a6a..4ddef4f 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1999,21 +1999,23 @@
 // set notify to true to broadcast a message to all contexts of the device loss
 bool Renderer9::testDeviceLost(bool notify)
 {
-    bool isLost = false;
+    HRESULT status = S_OK;
 
     if (mDeviceEx)
     {
-        isLost = FAILED(mDeviceEx->CheckDeviceState(NULL));
+        status = mDeviceEx->CheckDeviceState(NULL);
     }
     else if (mDevice)
     {
-        isLost = FAILED(mDevice->TestCooperativeLevel());
+        status = mDevice->TestCooperativeLevel();
     }
     else
     {
         // No device yet, so no reset required
     }
 
+    bool isLost = FAILED(status) || d3d9::isDeviceLostError(status);
+
     if (isLost)
     {
         // ensure we note the device loss --
@@ -2044,11 +2046,20 @@
         status = mDevice->TestCooperativeLevel();
     }
 
+    // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
+    // On some systems, they return S_PRESENT_MODE_CHANGED
+    // DEVICEREMOVED indicates the device has been stopped and must be recreated
     switch (status)
     {
       case D3DERR_DEVICENOTRESET:
       case D3DERR_DEVICEHUNG:
         return true;
+      case S_PRESENT_MODE_CHANGED:
+      case D3DERR_DEVICELOST:
+        return (mDeviceEx != NULL);
+      case D3DERR_DEVICEREMOVED:
+        UNIMPLEMENTED();
+        return false;
       default:
         return false;
     }