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
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
class BufferFactoryD3D : angle::NonCopyable
{
......
......@@ -15,8 +15,6 @@
namespace rx
{
static const int kDeviceLostCheckPeriod = 64;
//
// Template helpers for set and test operations.
//
......@@ -93,7 +91,8 @@ gl::Error FenceNV11::finish()
loopCount++;
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.";
}
......@@ -193,7 +192,8 @@ gl::Error Sync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResu
return error;
}
if ((loopCount % kDeviceLostCheckPeriod) == 0 && mRenderer->testDeviceLost())
bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (checkDeviceLost && mRenderer->testDeviceLost())
{
*outResult = GL_WAIT_FAILED;
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
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)
break;
}
if (!queryState->finished && mRenderer->testDeviceLost())
queryState->getDataAttemptCount++;
bool checkDeviceLost =
(queryState->getDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
if (!queryState->finished && checkDeviceLost && mRenderer->testDeviceLost())
{
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
......
......@@ -42,6 +42,8 @@ class Query11 : public QueryImpl
QueryState();
~QueryState();
unsigned int getDataAttemptCount;
d3d11::Query query;
d3d11::Query beginTimestamp;
d3d11::Query endTimestamp;
......
......@@ -1232,7 +1232,10 @@ gl::Error Renderer11::finish()
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();
return gl::OutOfMemory() << "Device was lost while waiting for sync.";
......
......@@ -16,6 +16,7 @@ namespace rx
{
Query9::Query9(Renderer9 *renderer, GLenum type)
: QueryImpl(type),
mGetDataAttemptCount(0),
mResult(GL_FALSE),
mQueryFinished(false),
mRenderer(renderer),
......@@ -170,15 +171,22 @@ gl::Error Query9::testQuery()
break;
}
if (d3d9::isDeviceLostError(result))
{
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
}
else if (mRenderer->testDeviceLost())
if (!mQueryFinished)
{
mRenderer->notifyDeviceLost();
return gl::OutOfMemory() << "Failed to test get query result, device is lost.";
if (d3d9::isDeviceLostError(result))
{
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
template <typename T>
gl::Error getResultBase(T *params);
unsigned int mGetDataAttemptCount;
GLuint64 mResult;
bool mQueryFinished;
......
......@@ -665,19 +665,25 @@ gl::Error Renderer9::finish()
}
// Loop until the query completes
unsigned int attempt = 0;
while (result == S_FALSE)
{
// Keep polling, but allow other threads to do something useful first
ScheduleYield();
result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
attempt++;
// 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
if (result == S_FALSE && testDeviceLost())
if (result == S_FALSE)
{
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))
......
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