Commit 9e83b593 by apatrick@chromium.org

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
parent 1615be20
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 554 #define BUILD_REVISION 556
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -27,8 +27,9 @@ Display::Display(HDC deviceContext) : mDc(deviceContext) ...@@ -27,8 +27,9 @@ Display::Display(HDC deviceContext) : mDc(deviceContext)
mD3d9Module = NULL; mD3d9Module = NULL;
mD3d9 = NULL; mD3d9 = NULL;
mD3d9ex = NULL; mD3d9Ex = NULL;
mDevice = NULL; mDevice = NULL;
mDeviceEx = NULL;
mDeviceWindow = NULL; mDeviceWindow = NULL;
mAdapter = D3DADAPTER_DEFAULT; mAdapter = D3DADAPTER_DEFAULT;
...@@ -68,10 +69,10 @@ bool Display::initialize() ...@@ -68,10 +69,10 @@ bool Display::initialize()
// Use Direct3D9Ex if available. Among other things, this version is less // Use Direct3D9Ex if available. Among other things, this version is less
// inclined to report a lost context, for example when the user switches // 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. // 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); ASSERT(mD3d9Ex);
mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
ASSERT(mD3d9); ASSERT(mD3d9);
} }
else else
...@@ -229,7 +230,7 @@ void Display::terminate() ...@@ -229,7 +230,7 @@ void Display::terminate()
if (mDevice) if (mDevice)
{ {
// If the device is lost, reset it first to prevent leaving the driver in an unstable state // If the device is lost, reset it first to prevent leaving the driver in an unstable state
if (FAILED(mDevice->TestCooperativeLevel())) if (isDeviceLost())
{ {
resetDevice(); resetDevice();
} }
...@@ -238,6 +239,12 @@ void Display::terminate() ...@@ -238,6 +239,12 @@ void Display::terminate()
mDevice = NULL; mDevice = NULL;
} }
if (mDeviceEx)
{
mDeviceEx->Release();
mDeviceEx = NULL;
}
if (mD3d9) if (mD3d9)
{ {
mD3d9->Release(); mD3d9->Release();
...@@ -250,10 +257,10 @@ void Display::terminate() ...@@ -250,10 +257,10 @@ void Display::terminate()
mDeviceWindow = NULL; mDeviceWindow = NULL;
} }
if (mD3d9ex) if (mD3d9Ex)
{ {
mD3d9ex->Release(); mD3d9Ex->Release();
mD3d9ex = NULL; mD3d9Ex = NULL;
} }
if (mD3d9Module) if (mD3d9Module)
...@@ -352,6 +359,12 @@ bool Display::createDevice() ...@@ -352,6 +359,12 @@ bool Display::createDevice()
} }
} }
if (mD3d9Ex)
{
result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
ASSERT(SUCCEEDED(result));
}
// Permanent non-default states // Permanent non-default states
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
...@@ -402,7 +415,7 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha ...@@ -402,7 +415,7 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
return NULL; return NULL;
} }
} }
else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device else if (isDeviceLost()) // Lost device
{ {
if (!resetDevice()) if (!resetDevice())
{ {
...@@ -435,7 +448,7 @@ void Display::destroyContext(gl::Context *context) ...@@ -435,7 +448,7 @@ void Display::destroyContext(gl::Context *context)
glDestroyContext(context); glDestroyContext(context);
mContextSet.erase(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++) for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{ {
...@@ -505,6 +518,18 @@ D3DCAPS9 Display::getDeviceCaps() ...@@ -505,6 +518,18 @@ D3DCAPS9 Display::getDeviceCaps()
return mDeviceCaps; return mDeviceCaps;
} }
bool Display::isDeviceLost()
{
if (mDeviceEx)
{
return FAILED(mDeviceEx->CheckDeviceState(NULL));
}
else
{
return FAILED(mDevice->TestCooperativeLevel());
}
}
void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
{ {
for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
...@@ -598,7 +623,7 @@ bool Display::getLuminanceAlphaTextureSupport() ...@@ -598,7 +623,7 @@ bool Display::getLuminanceAlphaTextureSupport()
D3DPOOL Display::getBufferPool(DWORD usage) const D3DPOOL Display::getBufferPool(DWORD usage) const
{ {
if (mD3d9ex != NULL) if (mD3d9Ex != NULL)
{ {
return D3DPOOL_DEFAULT; return D3DPOOL_DEFAULT;
} }
......
...@@ -59,6 +59,7 @@ class Display ...@@ -59,6 +59,7 @@ class Display
virtual IDirect3DDevice9 *getDevice(); virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps(); virtual D3DCAPS9 getDeviceCaps();
bool isDeviceLost();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport(); virtual bool getCompressedTextureSupport();
virtual bool getEventQuerySupport(); virtual bool getEventQuerySupport();
...@@ -80,8 +81,9 @@ class Display ...@@ -80,8 +81,9 @@ class Display
UINT mAdapter; UINT mAdapter;
D3DDEVTYPE mDeviceType; D3DDEVTYPE mDeviceType;
IDirect3D9 *mD3d9; // Always valid after successful initialization. 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; IDirect3DDevice9 *mDevice;
IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
D3DCAPS9 mDeviceCaps; D3DCAPS9 mDeviceCaps;
HWND mDeviceWindow; HWND mDeviceWindow;
......
...@@ -857,7 +857,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface ...@@ -857,7 +857,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
gl::Context *context = static_cast<gl::Context*>(ctx); gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice(); IDirect3DDevice9 *device = display->getDevice();
if (!device || FAILED(device->TestCooperativeLevel())) if (!device || display->isDeviceLost())
{ {
return error(EGL_CONTEXT_LOST, EGL_FALSE); return error(EGL_CONTEXT_LOST, EGL_FALSE);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment