Commit b66fd40e by Jamie Madill Committed by Shannon Woods

Proper handling of D3D9Ex device removed.

BUG=313210 Change-Id: I6b7e34466e89e7854c8797cbdcffc4a24c2c32f5
parent 0f0edf94
...@@ -42,6 +42,20 @@ void SafeRelease(T& resource) ...@@ -42,6 +42,20 @@ void SafeRelease(T& resource)
} }
} }
template <typename T>
void SafeDelete(T*& resource)
{
delete resource;
resource = NULL;
}
template <typename T>
void SafeDeleteArray(T*& resource)
{
delete[] resource;
resource = NULL;
}
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
......
...@@ -121,8 +121,6 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend ...@@ -121,8 +121,6 @@ Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Rend
Renderer9::~Renderer9() Renderer9::~Renderer9()
{ {
releaseDeviceResources();
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
...@@ -130,22 +128,19 @@ Renderer9::~Renderer9() ...@@ -130,22 +128,19 @@ Renderer9::~Renderer9()
{ {
resetDevice(); resetDevice();
} }
mDevice->Release();
mDevice = NULL;
} }
if (mDeviceEx) deinitialize();
{ }
mDeviceEx->Release();
mDeviceEx = NULL;
}
if (mD3d9) void Renderer9::deinitialize()
{ {
mD3d9->Release(); releaseDeviceResources();
mD3d9 = NULL;
} SafeRelease(mDevice);
SafeRelease(mDeviceEx);
SafeRelease(mD3d9);
SafeRelease(mD3d9Ex);
if (mDeviceWindow) if (mDeviceWindow)
{ {
...@@ -153,12 +148,6 @@ Renderer9::~Renderer9() ...@@ -153,12 +148,6 @@ Renderer9::~Renderer9()
mDeviceWindow = NULL; mDeviceWindow = NULL;
} }
if (mD3d9Ex)
{
mD3d9Ex->Release();
mD3d9Ex = NULL;
}
if (mD3d9Module) if (mD3d9Module)
{ {
mD3d9Module = NULL; mD3d9Module = NULL;
...@@ -2045,31 +2034,19 @@ void Renderer9::releaseDeviceResources() ...@@ -2045,31 +2034,19 @@ void Renderer9::releaseDeviceResources()
mEventQueryPool.pop_back(); mEventQueryPool.pop_back();
} }
if (mMaskedClearSavedState) SafeRelease(mMaskedClearSavedState);
{
mMaskedClearSavedState->Release();
mMaskedClearSavedState = NULL;
}
mVertexShaderCache.clear(); mVertexShaderCache.clear();
mPixelShaderCache.clear(); mPixelShaderCache.clear();
delete mBlit; SafeDelete(mBlit);
mBlit = NULL; SafeDelete(mVertexDataManager);
SafeDelete(mIndexDataManager);
delete mVertexDataManager; SafeDelete(mLineLoopIB);
mVertexDataManager = NULL;
delete mIndexDataManager;
mIndexDataManager = NULL;
delete mLineLoopIB;
mLineLoopIB = NULL;
for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
{ {
delete mNullColorbufferCache[i].buffer; SafeDelete(mNullColorbufferCache[i].buffer);
mNullColorbufferCache[i].buffer = NULL;
} }
} }
...@@ -2089,22 +2066,8 @@ bool Renderer9::isDeviceLost() ...@@ -2089,22 +2066,8 @@ bool Renderer9::isDeviceLost()
// set notify to true to broadcast a message to all contexts of the device loss // set notify to true to broadcast a message to all contexts of the device loss
bool Renderer9::testDeviceLost(bool notify) bool Renderer9::testDeviceLost(bool notify)
{ {
HRESULT status = S_OK; HRESULT status = getDeviceStatusCode();
bool isLost = (FAILED(status) || d3d9::isDeviceLostError(status));
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);
if (isLost) if (isLost)
{ {
...@@ -2123,7 +2086,7 @@ bool Renderer9::testDeviceLost(bool notify) ...@@ -2123,7 +2086,7 @@ bool Renderer9::testDeviceLost(bool notify)
return isLost; return isLost;
} }
bool Renderer9::testDeviceResettable() HRESULT Renderer9::getDeviceStatusCode()
{ {
HRESULT status = D3D_OK; HRESULT status = D3D_OK;
...@@ -2136,9 +2099,14 @@ bool Renderer9::testDeviceResettable() ...@@ -2136,9 +2099,14 @@ bool Renderer9::testDeviceResettable()
status = mDevice->TestCooperativeLevel(); status = mDevice->TestCooperativeLevel();
} }
return status;
}
bool Renderer9::testDeviceResettable()
{
// On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
// DEVICEREMOVED indicates the device has been stopped and must be recreated // DEVICEREMOVED indicates the device has been stopped and must be recreated
switch (status) switch (getDeviceStatusCode())
{ {
case D3DERR_DEVICENOTRESET: case D3DERR_DEVICENOTRESET:
case D3DERR_DEVICEHUNG: case D3DERR_DEVICEHUNG:
...@@ -2146,8 +2114,8 @@ bool Renderer9::testDeviceResettable() ...@@ -2146,8 +2114,8 @@ bool Renderer9::testDeviceResettable()
case D3DERR_DEVICELOST: case D3DERR_DEVICELOST:
return (mDeviceEx != NULL); return (mDeviceEx != NULL);
case D3DERR_DEVICEREMOVED: case D3DERR_DEVICEREMOVED:
UNIMPLEMENTED(); ASSERT(mDeviceEx != NULL);
return false; return true;
default: default:
return false; return false;
} }
...@@ -2162,13 +2130,22 @@ bool Renderer9::resetDevice() ...@@ -2162,13 +2130,22 @@ bool Renderer9::resetDevice()
HRESULT result = D3D_OK; HRESULT result = D3D_OK;
bool lost = testDeviceLost(false); bool lost = testDeviceLost(false);
int attempts = 3; int attempts = 3;
bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED);
while (lost && attempts > 0) while (lost && attempts > 0)
{ {
if (mDeviceEx) if (mDeviceEx)
{ {
Sleep(500); // Give the graphics driver some CPU time 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 else
{ {
...@@ -2195,13 +2172,29 @@ bool Renderer9::resetDevice() ...@@ -2195,13 +2172,29 @@ bool Renderer9::resetDevice()
return false; return false;
} }
// reset device defaults // If the device was removed, we already finished re-initialization in resetRemovedDevice
initializeDevice(); if (!removedDevice)
{
// reset device defaults
initializeDevice();
}
mDeviceLost = false; mDeviceLost = false;
return true; 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 DWORD Renderer9::getAdapterVendor() const
{ {
return mAdapterIdentifier.VendorId; return mAdapterIdentifier.VendorId;
......
...@@ -198,6 +198,8 @@ class Renderer9 : public Renderer ...@@ -198,6 +198,8 @@ class Renderer9 : public Renderer
private: private:
DISALLOW_COPY_AND_ASSIGN(Renderer9); DISALLOW_COPY_AND_ASSIGN(Renderer9);
void deinitialize();
void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v); void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v);
void applyUniformniv(gl::Uniform *targetUniform, const GLint *v); void applyUniformniv(gl::Uniform *targetUniform, const GLint *v);
void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v); void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v);
...@@ -218,6 +220,9 @@ class Renderer9 : public Renderer ...@@ -218,6 +220,9 @@ class Renderer9 : public Renderer
D3DPRESENT_PARAMETERS getDefaultPresentParameters(); D3DPRESENT_PARAMETERS getDefaultPresentParameters();
void releaseDeviceResources(); void releaseDeviceResources();
HRESULT getDeviceStatusCode();
HRESULT resetRemovedDevice();
UINT mAdapter; UINT mAdapter;
D3DDEVTYPE mDeviceType; D3DDEVTYPE mDeviceType;
bool mSoftwareDevice; // FIXME: Deprecate 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