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)
}
}
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)
#define snprintf _snprintf
#endif
......
......@@ -121,8 +121,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
......@@ -130,22 +128,19 @@ Renderer9::~Renderer9()
{
resetDevice();
}
mDevice->Release();
mDevice = NULL;
}
if (mDeviceEx)
{
mDeviceEx->Release();
mDeviceEx = NULL;
}
deinitialize();
}
if (mD3d9)
{
mD3d9->Release();
mD3d9 = NULL;
}
void Renderer9::deinitialize()
{
releaseDeviceResources();
SafeRelease(mDevice);
SafeRelease(mDeviceEx);
SafeRelease(mD3d9);
SafeRelease(mD3d9Ex);
if (mDeviceWindow)
{
......@@ -153,12 +148,6 @@ Renderer9::~Renderer9()
mDeviceWindow = NULL;
}
if (mD3d9Ex)
{
mD3d9Ex->Release();
mD3d9Ex = NULL;
}
if (mD3d9Module)
{
mD3d9Module = NULL;
......@@ -2045,31 +2034,19 @@ void Renderer9::releaseDeviceResources()
mEventQueryPool.pop_back();
}
if (mMaskedClearSavedState)
{
mMaskedClearSavedState->Release();
mMaskedClearSavedState = NULL;
}
SafeRelease(mMaskedClearSavedState);
mVertexShaderCache.clear();
mPixelShaderCache.clear();
delete mBlit;
mBlit = NULL;
delete mVertexDataManager;
mVertexDataManager = NULL;
delete mIndexDataManager;
mIndexDataManager = NULL;
delete mLineLoopIB;
mLineLoopIB = NULL;
SafeDelete(mBlit);
SafeDelete(mVertexDataManager);
SafeDelete(mIndexDataManager);
SafeDelete(mLineLoopIB);
for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
{
delete mNullColorbufferCache[i].buffer;
mNullColorbufferCache[i].buffer = NULL;
SafeDelete(mNullColorbufferCache[i].buffer);
}
}
......@@ -2089,22 +2066,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)
{
......@@ -2123,7 +2086,7 @@ bool Renderer9::testDeviceLost(bool notify)
return isLost;
}
bool Renderer9::testDeviceResettable()
HRESULT Renderer9::getDeviceStatusCode()
{
HRESULT status = D3D_OK;
......@@ -2136,9 +2099,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:
......@@ -2146,8 +2114,8 @@ bool Renderer9::testDeviceResettable()
case D3DERR_DEVICELOST:
return (mDeviceEx != NULL);
case D3DERR_DEVICEREMOVED:
UNIMPLEMENTED();
return false;
ASSERT(mDeviceEx != NULL);
return true;
default:
return false;
}
......@@ -2162,13 +2130,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
{
......@@ -2195,13 +2172,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;
......
......@@ -198,6 +198,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);
......@@ -218,6 +220,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