Commit 5528d11f by Geoff Lang Committed by Commit Bot

D3D: Don't test for device loss as frequenty in tight loops.

BUG=angleproject:1472 BUG=621240 Change-Id: I723839bd7961167adddcccc680638ae066eacea3 Reviewed-on: https://chromium-review.googlesource.com/1025645Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent f1bcd017
...@@ -73,6 +73,9 @@ enum RendererClass ...@@ -73,6 +73,9 @@ enum RendererClass
RENDERER_D3D9 RENDERER_D3D9
}; };
// Check if the device is lost every 10 failures to get the query data
constexpr unsigned int kPollingD3DDeviceLostCheckFrequency = 10;
// Useful for unit testing // Useful for unit testing
class BufferFactoryD3D : angle::NonCopyable class BufferFactoryD3D : angle::NonCopyable
{ {
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
namespace rx namespace rx
{ {
static const int kDeviceLostCheckPeriod = 64;
// //
// Template helpers for set and test operations. // Template helpers for set and test operations.
// //
...@@ -93,7 +91,8 @@ gl::Error FenceNV11::finish() ...@@ -93,7 +91,8 @@ gl::Error FenceNV11::finish()
loopCount++; loopCount++;
ANGLE_TRY(FenceTestHelper(this, true, &finished)); ANGLE_TRY(FenceTestHelper(this, true, &finished));
if (loopCount % kDeviceLostCheckPeriod == 0 && mRenderer->testDeviceLost()) bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && mRenderer->testDeviceLost())
{ {
return gl::OutOfMemory() << "Device was lost while querying result of an event query."; return gl::OutOfMemory() << "Device was lost while querying result of an event query.";
} }
...@@ -193,7 +192,8 @@ gl::Error Sync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResu ...@@ -193,7 +192,8 @@ gl::Error Sync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResu
return error; return error;
} }
if ((loopCount % kDeviceLostCheckPeriod) == 0 && mRenderer->testDeviceLost()) bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && mRenderer->testDeviceLost())
{ {
*outResult = GL_WAIT_FAILED; *outResult = GL_WAIT_FAILED;
return gl::OutOfMemory() << "Device was lost while querying result of an event query."; return gl::OutOfMemory() << "Device was lost while querying result of an event query.";
......
...@@ -48,7 +48,8 @@ GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResu ...@@ -48,7 +48,8 @@ GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResu
namespace rx namespace rx
{ {
Query11::QueryState::QueryState() : query(), beginTimestamp(), endTimestamp(), finished(false) Query11::QueryState::QueryState()
: getDataAttemptCount(0), query(), beginTimestamp(), endTimestamp(), finished(false)
{ {
} }
...@@ -362,7 +363,10 @@ gl::Error Query11::testQuery(QueryState *queryState) ...@@ -362,7 +363,10 @@ gl::Error Query11::testQuery(QueryState *queryState)
break; break;
} }
if (!queryState->finished && mRenderer->testDeviceLost()) queryState->getDataAttemptCount++;
bool checkDeviceLost =
(queryState->getDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (!queryState->finished && checkDeviceLost && mRenderer->testDeviceLost())
{ {
mRenderer->notifyDeviceLost(); mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost."; return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
......
...@@ -42,6 +42,8 @@ class Query11 : public QueryImpl ...@@ -42,6 +42,8 @@ class Query11 : public QueryImpl
QueryState(); QueryState();
~QueryState(); ~QueryState();
unsigned int getDataAttemptCount;
d3d11::Query query; d3d11::Query query;
d3d11::Query beginTimestamp; d3d11::Query beginTimestamp;
d3d11::Query endTimestamp; d3d11::Query endTimestamp;
......
...@@ -1232,7 +1232,10 @@ gl::Error Renderer11::finish() ...@@ -1232,7 +1232,10 @@ gl::Error Renderer11::finish()
ScheduleYield(); ScheduleYield();
} }
if (testDeviceLost()) // Attempt is incremented before checking if we should test for device loss so that device
// loss is not checked on the first iteration
bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && testDeviceLost())
{ {
mDisplay->notifyDeviceLost(); mDisplay->notifyDeviceLost();
return gl::OutOfMemory() << "Device was lost while waiting for sync."; return gl::OutOfMemory() << "Device was lost while waiting for sync.";
......
...@@ -16,6 +16,7 @@ namespace rx ...@@ -16,6 +16,7 @@ namespace rx
{ {
Query9::Query9(Renderer9 *renderer, GLenum type) Query9::Query9(Renderer9 *renderer, GLenum type)
: QueryImpl(type), : QueryImpl(type),
mGetDataAttemptCount(0),
mResult(GL_FALSE), mResult(GL_FALSE),
mQueryFinished(false), mQueryFinished(false),
mRenderer(renderer), mRenderer(renderer),
...@@ -170,15 +171,22 @@ gl::Error Query9::testQuery() ...@@ -170,15 +171,22 @@ gl::Error Query9::testQuery()
break; break;
} }
if (d3d9::isDeviceLostError(result)) if (!mQueryFinished)
{
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
}
else if (mRenderer->testDeviceLost())
{ {
mRenderer->notifyDeviceLost(); if (d3d9::isDeviceLostError(result))
return gl::OutOfMemory() << "Failed to test get query result, device is lost."; {
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
}
mGetDataAttemptCount++;
bool checkDeviceLost =
(mGetDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && mRenderer->testDeviceLost())
{
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
}
} }
} }
......
...@@ -36,6 +36,7 @@ class Query9 : public QueryImpl ...@@ -36,6 +36,7 @@ class Query9 : public QueryImpl
template <typename T> template <typename T>
gl::Error getResultBase(T *params); gl::Error getResultBase(T *params);
unsigned int mGetDataAttemptCount;
GLuint64 mResult; GLuint64 mResult;
bool mQueryFinished; bool mQueryFinished;
......
...@@ -665,19 +665,25 @@ gl::Error Renderer9::finish() ...@@ -665,19 +665,25 @@ gl::Error Renderer9::finish()
} }
// Loop until the query completes // Loop until the query completes
unsigned int attempt = 0;
while (result == S_FALSE) while (result == S_FALSE)
{ {
// Keep polling, but allow other threads to do something useful first // Keep polling, but allow other threads to do something useful first
ScheduleYield(); ScheduleYield();
result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
attempt++;
// explicitly check for device loss if (result == S_FALSE)
// some drivers seem to return S_FALSE even if the device is lost
// instead of D3DERR_DEVICELOST like they should
if (result == S_FALSE && testDeviceLost())
{ {
result = D3DERR_DEVICELOST; // explicitly check for device loss
// some drivers seem to return S_FALSE even if the device is lost
// instead of D3DERR_DEVICELOST like they should
bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && testDeviceLost())
{
result = D3DERR_DEVICELOST;
}
} }
if (FAILED(result)) if (FAILED(result))
......
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