Commit 8b76d37f by Jamie Madill Committed by Commit Bot

Trace Tests: Run one step per frame.

Instead of trying to make one step take one sequence of frames, one run step per frame always. This will scale better for traces that are very long and cannot complete in the short times we use on the bots. Adds an explicit step round-up feature so that we can always run chunks of full trace sequences when we are not running with a fixed maximum number of steps. Bug: b/172977194 Change-Id: I0f069a66a86d8c4a698ebffb66782d13843539a5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2545884Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 995493cc
......@@ -11,6 +11,7 @@
#include "ANGLEPerfTestArgs.h"
#include "common/debug.h"
#include "common/mathutil.h"
#include "common/platform.h"
#include "common/system_utils.h"
#include "common/utilities.h"
......@@ -220,7 +221,6 @@ ANGLEPerfTest::ANGLEPerfTest(const std::string &name,
mStepsToRun(std::max(gStepsPerTrial, gMaxStepsPerformed)),
mTrialNumStepsPerformed(0),
mTotalNumStepsPerformed(0),
mStepsPerRunLoopStep(1),
mIterationsPerStep(iterationsPerStep),
mRunning(true)
{
......@@ -295,12 +295,6 @@ void ANGLEPerfTest::run()
}
}
void ANGLEPerfTest::setStepsPerRunLoopStep(int stepsPerRunLoop)
{
ASSERT(stepsPerRunLoop >= 1);
mStepsPerRunLoopStep = stepsPerRunLoop;
}
void ANGLEPerfTest::doRunLoop(double maxRunTime, int maxStepsToRun, RunLoopPolicy runPolicy)
{
mTrialNumStepsPerformed = 0;
......@@ -320,9 +314,13 @@ void ANGLEPerfTest::doRunLoop(double maxRunTime, int maxStepsToRun, RunLoopPolic
if (mRunning)
{
mTrialNumStepsPerformed += mStepsPerRunLoopStep;
mTotalNumStepsPerformed += mStepsPerRunLoopStep;
if (mTimer.getElapsedTime() > maxRunTime)
mTrialNumStepsPerformed++;
mTotalNumStepsPerformed++;
if (gMaxStepsPerformed > 0 && mTotalNumStepsPerformed >= gMaxStepsPerformed)
{
mRunning = false;
}
else if (mTimer.getElapsedTime() > maxRunTime)
{
mRunning = false;
}
......@@ -432,6 +430,11 @@ void ANGLEPerfTest::calibrateStepsToRun()
mStepsToRun = static_cast<unsigned int>(static_cast<double>(mTrialNumStepsPerformed) * scale);
mStepsToRun = std::max(1, mStepsToRun);
if (getStepAlignment() != 1)
{
mStepsToRun = rx::roundUp(mStepsToRun, getStepAlignment());
}
if (gVerboseLogging)
{
printf(
......@@ -449,6 +452,12 @@ void ANGLEPerfTest::calibrateStepsToRun()
}
}
int ANGLEPerfTest::getStepAlignment() const
{
// Default: No special alignment rules.
return 1;
}
std::string RenderTestParams::backend() const
{
std::stringstream strstr;
......
......@@ -78,6 +78,9 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
virtual void finishTest() {}
virtual void flush() {}
// Can be overridden in child tests that require a certain number of steps per trial.
virtual int getStepAlignment() const;
protected:
enum class RunLoopPolicy
{
......@@ -97,8 +100,6 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
int getNumStepsPerformed() const { return mTrialNumStepsPerformed; }
// Defaults to one step per run loop. Can be changed in any test.
void setStepsPerRunLoopStep(int stepsPerRunLoop);
void doRunLoop(double maxRunTime, int maxStepsToRun, RunLoopPolicy runPolicy);
// Overriden in trace perf tests.
......@@ -118,7 +119,6 @@ class ANGLEPerfTest : public testing::Test, angle::NonCopyable
int mStepsToRun;
int mTrialNumStepsPerformed;
int mTotalNumStepsPerformed;
int mStepsPerRunLoopStep;
int mIterationsPerStep;
bool mRunning;
std::vector<double> mTestTrialResults;
......
......@@ -89,6 +89,13 @@ class TracePerfTest : public ANGLERenderTest, public ::testing::WithParamInterfa
double getHostTimeFromGLTime(GLint64 glTime);
int getStepAlignment() const override
{
// Align step counts to the number of frames in a trace.
const TraceInfo &traceInfo = GetTraceInfo(GetParam().testID);
return static_cast<int>(traceInfo.endFrame - traceInfo.startFrame + 1);
}
private:
struct QueryInfo
{
......@@ -120,6 +127,8 @@ class TracePerfTest : public ANGLERenderTest, public ::testing::WithParamInterfa
int mWindowHeight = 0;
GLuint mDrawFramebufferBinding = 0;
GLuint mReadFramebufferBinding = 0;
uint32_t mCurrentFrame = 0;
uint32_t mOffscreenFrameCount = 0;
};
class TracePerfTest;
......@@ -293,8 +302,6 @@ void TracePerfTest::initializeBenchmark()
mEndFrame = traceInfo.endFrame;
SetBinaryDataDecompressCallback(params.testID, DecompressBinaryData);
setStepsPerRunLoopStep(mEndFrame - mStartFrame + 1);
std::stringstream testDataDirStr;
testDataDirStr << ANGLE_TRACE_DATA_DIR << "/" << traceInfo.name;
std::string testDataDir = testDataDirStr.str();
......@@ -302,6 +309,7 @@ void TracePerfTest::initializeBenchmark()
mWindowWidth = mTestParams.windowWidth;
mWindowHeight = mTestParams.windowHeight;
mCurrentFrame = mStartFrame;
if (IsAndroid())
{
......@@ -426,88 +434,86 @@ void TracePerfTest::drawBenchmark()
const TracePerfParams &params = GetParam();
// Add a time sample from GL and the host.
sampleTime();
uint32_t endFrame = mEndFrame;
if (gMaxStepsPerformed > 0)
if (mCurrentFrame == mStartFrame)
{
endFrame =
std::min(endFrame, gMaxStepsPerformed - mTotalNumStepsPerformed - 1 + mStartFrame);
mStepsPerRunLoopStep = endFrame - mStartFrame + 1;
sampleTime();
}
for (uint32_t frame = mStartFrame; frame <= mEndFrame; ++frame)
char frameName[32];
sprintf(frameName, "Frame %u", mCurrentFrame);
beginInternalTraceEvent(frameName);
startGpuTimer();
ReplayFrame(params.testID, mCurrentFrame);
stopGpuTimer();
if (params.surfaceType == SurfaceType::Offscreen)
{
char frameName[32];
sprintf(frameName, "Frame %u", frame);
beginInternalTraceEvent(frameName);
GLint currentDrawFBO, currentReadFBO;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &currentDrawFBO);
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &currentReadFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mOffscreenFramebuffer);
uint32_t frameX = (mOffscreenFrameCount % kFramesPerXY) % kFramesPerX;
uint32_t frameY = (mOffscreenFrameCount % kFramesPerXY) / kFramesPerX;
uint32_t windowX = kOffscreenOffsetX + frameX * kOffscreenFrameWidth;
uint32_t windowY = kOffscreenOffsetY + frameY * kOffscreenFrameHeight;
if (gVerboseLogging)
{
printf("Frame %d: x %d y %d (screen x %d, screen y %d)\n", mOffscreenFrameCount, frameX,
frameY, windowX, windowY);
}
GLboolean scissorTest = GL_FALSE;
glGetBooleanv(GL_SCISSOR_TEST, &scissorTest);
startGpuTimer();
ReplayFrame(params.testID, frame);
stopGpuTimer();
if (scissorTest)
{
glDisable(GL_SCISSOR_TEST);
}
if (params.surfaceType != SurfaceType::Offscreen)
glBlitFramebuffer(0, 0, mWindowWidth, mWindowHeight, windowX, windowY,
windowX + kOffscreenFrameWidth, windowY + kOffscreenFrameHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
if (frameX == kFramesPerX - 1 && frameY == kFramesPerY - 1)
{
getGLWindow()->swap();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
mOffscreenFrameCount = 0;
}
else
{
GLint currentDrawFBO, currentReadFBO;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &currentDrawFBO);
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &currentReadFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mOffscreenFramebuffer);
uint32_t frames = getNumStepsPerformed() + (frame - mStartFrame);
uint32_t frameX = (frames % kFramesPerXY) % kFramesPerX;
uint32_t frameY = (frames % kFramesPerXY) / kFramesPerX;
uint32_t windowX = kOffscreenOffsetX + frameX * kOffscreenFrameWidth;
uint32_t windowY = kOffscreenOffsetY + frameY * kOffscreenFrameHeight;
if (angle::gVerboseLogging)
{
printf("Frame %d: x %d y %d (screen x %d, screen y %d)\n", frames, frameX, frameY,
windowX, windowY);
}
GLboolean scissorTest = GL_FALSE;
glGetBooleanv(GL_SCISSOR_TEST, &scissorTest);
if (scissorTest)
{
glDisable(GL_SCISSOR_TEST);
}
glBlitFramebuffer(0, 0, mWindowWidth, mWindowHeight, windowX, windowY,
windowX + kOffscreenFrameWidth, windowY + kOffscreenFrameHeight,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
if (frameX == kFramesPerX - 1 && frameY == kFramesPerY - 1)
{
getGLWindow()->swap();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
if (scissorTest)
{
glEnable(GL_SCISSOR_TEST);
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentDrawFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFBO);
mOffscreenFrameCount++;
}
endInternalTraceEvent(frameName);
// Check for abnormal exit.
if (!mRunning)
if (scissorTest)
{
return;
glEnable(GL_SCISSOR_TEST);
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentDrawFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFBO);
}
else
{
getGLWindow()->swap();
}
endInternalTraceEvent(frameName);
ResetReplay(params.testID);
if (mCurrentFrame == mEndFrame)
{
ResetReplay(params.testID);
mCurrentFrame = mStartFrame;
}
else
{
mCurrentFrame++;
}
// Process any running queries once per iteration.
for (size_t queryIndex = 0; queryIndex < mRunningQueries.size();)
......
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