Commit 4704eb02 by Shahbaz Youssefi Committed by Commit Bot

Add possibility to track GPU time in perf tests

This paves the way for perf tests that measure GPU performance. Bug: angleproject:2999 Change-Id: I9d49d3e1256d8d18514885ae63264a5fbc5c29d1 Reviewed-on: https://chromium-review.googlesource.com/c/1436839 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 4c94788c
......@@ -170,6 +170,7 @@ ANGLEPerfTest::ANGLEPerfTest(const std::string &name,
: mName(name),
mSuffix(suffix),
mTimer(CreateTimer()),
mGPUTimeNs(0),
mSkipTest(false),
mStepsToRun(std::numeric_limits<unsigned int>::max()),
mNumStepsPerformed(0),
......@@ -225,6 +226,7 @@ void ANGLEPerfTest::doRunLoop(double maxRunTime)
mNumStepsPerformed = 0;
mRunning = true;
mTimer->start();
startTest();
while (mRunning)
{
......@@ -268,21 +270,35 @@ void ANGLEPerfTest::TearDown() {}
void ANGLEPerfTest::printResults()
{
double elapsedTimeSeconds = mTimer->getElapsedTime();
double elapsedTimeSeconds[2] = {
mTimer->getElapsedTime(),
mGPUTimeNs * 1e-9,
};
double secondsPerStep = elapsedTimeSeconds / static_cast<double>(mNumStepsPerformed);
double secondsPerIteration = secondsPerStep / static_cast<double>(mIterationsPerStep);
const char *clockNames[2] = {
"wall_time",
"gpu_time",
};
// Give the result a different name to ensure separate graphs if we transition.
if (secondsPerIteration > 1e-3)
{
double microSecondsPerIteration = secondsPerIteration * kMicroSecondsPerSecond;
printResult("wall_time", microSecondsPerIteration, "us", true);
}
else
// If measured gpu time is non-zero, print that too.
size_t clocksToOutput = mGPUTimeNs > 0 ? 2 : 1;
for (size_t i = 0; i < clocksToOutput; ++i)
{
double nanoSecPerIteration = secondsPerIteration * kNanoSecondsPerSecond;
printResult("wall_time", nanoSecPerIteration, "ns", true);
double secondsPerStep = elapsedTimeSeconds[i] / static_cast<double>(mNumStepsPerformed);
double secondsPerIteration = secondsPerStep / static_cast<double>(mIterationsPerStep);
// Give the result a different name to ensure separate graphs if we transition.
if (secondsPerIteration > 1e-3)
{
double microSecondsPerIteration = secondsPerIteration * kMicroSecondsPerSecond;
printResult(clockNames[i], microSecondsPerIteration, "us", true);
}
else
{
double nanoSecPerIteration = secondsPerIteration * kNanoSecondsPerSecond;
printResult(clockNames[i], nanoSecPerIteration, "ns", true);
}
}
}
......@@ -505,8 +521,41 @@ void ANGLERenderTest::step()
}
}
void ANGLERenderTest::startGpuTimer()
{
if (mTestParams.trackGpuTime)
{
glBeginQueryEXT(GL_TIME_ELAPSED_EXT, mTimestampQuery);
}
}
void ANGLERenderTest::stopGpuTimer()
{
if (mTestParams.trackGpuTime)
{
glEndQueryEXT(GL_TIME_ELAPSED_EXT);
uint64_t gpuTimeNs = 0;
glGetQueryObjectui64vEXT(mTimestampQuery, GL_QUERY_RESULT_EXT, &gpuTimeNs);
mGPUTimeNs += gpuTimeNs;
}
}
void ANGLERenderTest::startTest()
{
if (mTestParams.trackGpuTime)
{
glGenQueriesEXT(1, &mTimestampQuery);
mGPUTimeNs = 0;
}
}
void ANGLERenderTest::finishTest()
{
if (mTestParams.trackGpuTime)
{
glDeleteQueriesEXT(1, &mTimestampQuery);
}
if (mTestParams.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE)
{
glFinish();
......
......@@ -61,6 +61,8 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
virtual void step() = 0;
// Called right after the timer starts to let the test initialize other metrics if necessary
virtual void startTest() {}
// Called right before timer is stopped to let the test wait for asynchronous operations.
virtual void finishTest() {}
......@@ -91,6 +93,7 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
std::string mName;
std::string mSuffix;
Timer *mTimer;
uint64_t mGPUTimeNs;
bool mSkipTest;
private:
......@@ -111,6 +114,7 @@ struct RenderTestParams : public angle::PlatformParameters
EGLint windowWidth = 64;
EGLint windowHeight = 64;
unsigned int iterationsPerStep = 0;
bool trackGpuTime = false;
};
class ANGLERenderTest : public ANGLEPerfTest
......@@ -140,11 +144,15 @@ class ANGLERenderTest : public ANGLEPerfTest
void setWebGLCompatibilityEnabled(bool webglCompatibility);
void setRobustResourceInit(bool enabled);
void startGpuTimer();
void stopGpuTimer();
private:
void SetUp() override;
void TearDown() override;
void step() override;
void startTest() override;
void finishTest() override;
bool areExtensionPrerequisitesFulfilled() const;
......@@ -156,6 +164,8 @@ class ANGLERenderTest : public ANGLEPerfTest
std::vector<const char *> mExtensionPrerequisites;
angle::PlatformMethods mPlatformMethods;
GLuint mTimestampQuery;
// Trace event record that can be output.
std::vector<TraceEvent> mTraceEventBuffer;
......
......@@ -104,4 +104,4 @@ DrawCallPerfParams DrawCallPerfWGLParams(bool renderToTexture)
params.useFBO = renderToTexture;
params.driver = angle::GLESDriverType::SystemWGL;
return params;
}
\ No newline at end of file
}
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