Commit b7935e51 by Jamie Madill

Proper handling of D3D9Ex device removed.

BUG=313210 Change-Id: I85dae10bc2ec38a1e9c09f318b8f6b9196466d60
parent bf551589
......@@ -131,8 +131,6 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend
Renderer9::~Renderer9()
{
releaseDeviceResources();
if (mDevice)
{
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
......@@ -140,12 +138,19 @@ Renderer9::~Renderer9()
{
resetDevice();
}
SafeRelease(mDevice);
}
deinitialize();
}
void Renderer9::deinitialize()
{
releaseDeviceResources();
SafeRelease(mDevice);
SafeRelease(mDeviceEx);
SafeRelease(mD3d9);
SafeRelease(mD3d9Ex);
if (mDeviceWindow)
{
......@@ -153,8 +158,6 @@ Renderer9::~Renderer9()
mDeviceWindow = NULL;
}
SafeRelease(mD3d9Ex);
mD3d9Module = NULL;
}
......@@ -2095,22 +2098,8 @@ bool Renderer9::isDeviceLost()
// set notify to true to broadcast a message to all contexts of the device loss
bool Renderer9::testDeviceLost(bool notify)
{
HRESULT status = S_OK;
if (mDeviceEx)
{
status = mDeviceEx->CheckDeviceState(NULL);
}
else if (mDevice)
{
status = mDevice->TestCooperativeLevel();
}
else
{
// No device yet, so no reset required
}
bool isLost = FAILED(status) || d3d9::isDeviceLostError(status);
HRESULT status = getDeviceStatusCode();
bool isLost = (FAILED(status) || d3d9::isDeviceLostError(status));
if (isLost)
{
......@@ -2129,7 +2118,7 @@ bool Renderer9::testDeviceLost(bool notify)
return isLost;
}
bool Renderer9::testDeviceResettable()
HRESULT Renderer9::getDeviceStatusCode()
{
HRESULT status = D3D_OK;
......@@ -2142,9 +2131,14 @@ bool Renderer9::testDeviceResettable()
status = mDevice->TestCooperativeLevel();
}
return status;
}
bool Renderer9::testDeviceResettable()
{
// On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
// DEVICEREMOVED indicates the device has been stopped and must be recreated
switch (status)
switch (getDeviceStatusCode())
{
case D3DERR_DEVICENOTRESET:
case D3DERR_DEVICEHUNG:
......@@ -2152,8 +2146,8 @@ bool Renderer9::testDeviceResettable()
case D3DERR_DEVICELOST:
return (mDeviceEx != NULL);
case D3DERR_DEVICEREMOVED:
UNIMPLEMENTED();
return false;
ASSERT(mDeviceEx != NULL);
return true;
default:
return false;
}
......@@ -2168,13 +2162,22 @@ bool Renderer9::resetDevice()
HRESULT result = D3D_OK;
bool lost = testDeviceLost(false);
int attempts = 3;
bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED);
while (lost && attempts > 0)
{
if (mDeviceEx)
{
Sleep(500); // Give the graphics driver some CPU time
result = mDeviceEx->ResetEx(&presentParameters, NULL);
if (removedDevice)
{
result = resetRemovedDevice();
}
else
{
result = mDeviceEx->ResetEx(&presentParameters, NULL);
}
}
else
{
......@@ -2201,13 +2204,29 @@ bool Renderer9::resetDevice()
return false;
}
// reset device defaults
initializeDevice();
// If the device was removed, we already finished re-initialization in resetRemovedDevice
if (!removedDevice)
{
// reset device defaults
initializeDevice();
}
mDeviceLost = false;
return true;
}
HRESULT Renderer9::resetRemovedDevice()
{
// From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx:
// The hardware adapter has been removed. Application must destroy the device, do enumeration of
// adapters and create another Direct3D device. If application continues rendering without
// calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only.
ASSERT(mDeviceEx != NULL);
deinitialize();
return (initialize() == EGL_SUCCESS ? S_OK : S_FALSE);
}
DWORD Renderer9::getAdapterVendor() const
{
return mAdapterIdentifier.VendorId;
......
......@@ -233,6 +233,8 @@ class Renderer9 : public Renderer
private:
DISALLOW_COPY_AND_ASSIGN(Renderer9);
void deinitialize();
void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v);
void applyUniformniv(gl::Uniform *targetUniform, const GLint *v);
void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v);
......@@ -252,6 +254,9 @@ class Renderer9 : public Renderer
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
void releaseDeviceResources();
HRESULT getDeviceStatusCode();
HRESULT resetRemovedDevice();
UINT mAdapter;
D3DDEVTYPE mDeviceType;
bool mSoftwareDevice; // FIXME: Deprecate
......
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