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 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)
......
......@@ -27,8 +27,9 @@ Display::Display(HDC deviceContext) : mDc(deviceContext)
mD3d9Module = NULL;
mD3d9 = NULL;
mD3d9ex = NULL;
mD3d9Ex = NULL;
mDevice = NULL;
mDeviceEx = NULL;
mDeviceWindow = NULL;
mAdapter = D3DADAPTER_DEFAULT;
......@@ -68,10 +69,10 @@ bool Display::initialize()
// 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 @@ void Display::terminate()
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 @@ void Display::terminate()
mDevice = NULL;
}
if (mDeviceEx)
{
mDeviceEx->Release();
mDeviceEx = NULL;
}
if (mD3d9)
{
mD3d9->Release();
......@@ -250,10 +257,10 @@ void Display::terminate()
mDeviceWindow = NULL;
}
if (mD3d9ex)
if (mD3d9Ex)
{
mD3d9ex->Release();
mD3d9ex = NULL;
mD3d9Ex->Release();
mD3d9Ex = NULL;
}
if (mD3d9Module)
......@@ -352,6 +359,12 @@ bool Display::createDevice()
}
}
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 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
return NULL;
}
}
else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device
else if (isDeviceLost()) // Lost device
{
if (!resetDevice())
{
......@@ -435,7 +448,7 @@ void Display::destroyContext(gl::Context *context)
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 @@ D3DCAPS9 Display::getDeviceCaps()
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 @@ bool Display::getLuminanceAlphaTextureSupport()
D3DPOOL Display::getBufferPool(DWORD usage) const
{
if (mD3d9ex != NULL)
if (mD3d9Ex != NULL)
{
return D3DPOOL_DEFAULT;
}
......
......@@ -59,6 +59,7 @@ class Display
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 @@ class Display
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;
......
......@@ -857,7 +857,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
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);
}
......
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