Check for device lost with CheckDeviceState when using D3D9Ex.
According to the docs, TestCooperativeLevel is a no-op with D3D9Ex.
http://msdn.microsoft.com/en-us/library/bb174348(VS.85).aspx
I believe it is safe to ignore the additional return values from CheckDeviceState. Some appear to be to allow optimization when a window is occluded. The new errors seem to be best treated as device lost as we were before. Although if the device is removed (!) I'm not sure what to do. It might also be useful to communicate D3DERR_DEVICEHUNG to Chromium in the future so it can use it as a hint to back off.
Tested that D3D9 and D3D9Ex take the appropriate paths through Display::isDeviceLost.
Bug: http://code.google.com/p/angleproject/issues/detail?id=113
Review URL: http://codereview.appspot.com/4154042
git-svn-id: https://angleproject.googlecode.com/svn/trunk@557 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/common/version.h b/src/common/version.h
index b403781..853300c 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
-#define BUILD_REVISION 554
+#define BUILD_REVISION 556
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index bcda895..4673e73 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -27,8 +27,9 @@
mD3d9Module = NULL;
mD3d9 = NULL;
- mD3d9ex = NULL;
+ mD3d9Ex = NULL;
mDevice = NULL;
+ mDeviceEx = NULL;
mDeviceWindow = NULL;
mAdapter = D3DADAPTER_DEFAULT;
@@ -68,10 +69,10 @@
// Use Direct3D9Ex if available. Among other things, this version is less
// inclined to report a lost context, for example when the user switches
// desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
- if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+ if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
{
- ASSERT(mD3d9ex);
- mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+ ASSERT(mD3d9Ex);
+ mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
ASSERT(mD3d9);
}
else
@@ -229,7 +230,7 @@
if (mDevice)
{
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
- if (FAILED(mDevice->TestCooperativeLevel()))
+ if (isDeviceLost())
{
resetDevice();
}
@@ -238,6 +239,12 @@
mDevice = NULL;
}
+ if (mDeviceEx)
+ {
+ mDeviceEx->Release();
+ mDeviceEx = NULL;
+ }
+
if (mD3d9)
{
mD3d9->Release();
@@ -250,10 +257,10 @@
mDeviceWindow = NULL;
}
- if (mD3d9ex)
+ if (mD3d9Ex)
{
- mD3d9ex->Release();
- mD3d9ex = NULL;
+ mD3d9Ex->Release();
+ mD3d9Ex = NULL;
}
if (mD3d9Module)
@@ -352,6 +359,12 @@
}
}
+ if (mD3d9Ex)
+ {
+ result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
+ ASSERT(SUCCEEDED(result));
+ }
+
// Permanent non-default states
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
@@ -402,7 +415,7 @@
return NULL;
}
}
- else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device
+ else if (isDeviceLost()) // Lost device
{
if (!resetDevice())
{
@@ -435,7 +448,7 @@
glDestroyContext(context);
mContextSet.erase(context);
- if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device
+ if (mContextSet.empty() && mDevice && isDeviceLost()) // Last context of a lost device
{
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
@@ -505,6 +518,18 @@
return mDeviceCaps;
}
+bool Display::isDeviceLost()
+{
+ if (mDeviceEx)
+ {
+ return FAILED(mDeviceEx->CheckDeviceState(NULL));
+ }
+ else
+ {
+ return FAILED(mDevice->TestCooperativeLevel());
+ }
+}
+
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
{
for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
@@ -598,7 +623,7 @@
D3DPOOL Display::getBufferPool(DWORD usage) const
{
- if (mD3d9ex != NULL)
+ if (mD3d9Ex != NULL)
{
return D3DPOOL_DEFAULT;
}
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index 4b74e1e..c87d5ec 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -59,6 +59,7 @@
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
+ bool isDeviceLost();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport();
virtual bool getEventQuerySupport();
@@ -80,8 +81,9 @@
UINT mAdapter;
D3DDEVTYPE mDeviceType;
IDirect3D9 *mD3d9; // Always valid after successful initialization.
- IDirect3D9Ex *mD3d9ex; // Might be null if D3D9Ex is not supported.
+ IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported.
IDirect3DDevice9 *mDevice;
+ IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
D3DCAPS9 mDeviceCaps;
HWND mDeviceWindow;
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 5de59aa..4f97fd5 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -857,7 +857,7 @@
gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice();
- if (!device || FAILED(device->TestCooperativeLevel()))
+ if (!device || display->isDeviceLost())
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}