Hash :
8047f065
Author :
Date :
2015-12-15T17:54:42
Improve perf testing framework The ANGLERenderTest subclasses have a parameter "iterations". Previously most of these tests would perform iterations^2 iterations, since the looping was done both in ANGLERenderTest and in the individual test classes. Do the looping only in the individual test classes instead. This enables getting rid of separate beginDrawBenchmark() and endDrawBenchmark() functions. Some other unused code is also removed: 1. stepBenchmark function 2. unused parameters to step() This makes the core loop of running tests simpler. The perf testing framework also now has shared logic for deciding when to end a given test. The score calculation for tests is also changed. Instead of reporting just the number of operations done, it is reported relative to the actual run time of the test. This should make the test results more accurate, since run time of the tests may have some variation. It also enables changing the run time of the tests without rebaselining them. In the tests that use GPU, GPU operations are also waited to finish before stopping the timer. BUG=angleproject:1261 TEST=angle_perftests Change-Id: I69e9aad8afd2d9dedd60e144f0a5d4203618feef Reviewed-on: https://chromium-review.googlesource.com/319381 Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com> Tested-by: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IndexConversionPerf:
// Performance tests for ANGLE index conversion in D3D11.
//
#include <sstream>
#include "ANGLEPerfTest.h"
#include "shader_utils.h"
using namespace angle;
namespace
{
struct IndexConversionPerfParams final : public RenderTestParams
{
std::string suffix() const override
{
std::stringstream strstr;
strstr << RenderTestParams::suffix();
return strstr.str();
}
unsigned int iterations;
unsigned int numIndexTris;
};
// Provide a custom gtest parameter name function for IndexConversionPerfParams
// that includes the number of iterations and triangles in the test parameter name.
// This also fixes the resolution of the overloaded operator<< on MSVC.
std::ostream &operator<<(std::ostream &stream, const IndexConversionPerfParams ¶m)
{
const PlatformParameters &platform = param;
stream << platform << "_" << param.iterations << "_" << param.numIndexTris;
return stream;
}
class IndexConversionPerfTest : public ANGLERenderTest,
public ::testing::WithParamInterface<IndexConversionPerfParams>
{
public:
IndexConversionPerfTest();
void initializeBenchmark() override;
void destroyBenchmark() override;
void drawBenchmark() override;
void updateBufferData();
private:
GLuint mProgram;
GLuint mVertexBuffer;
GLuint mIndexBuffer;
std::vector<GLushort> mIndexData;
};
IndexConversionPerfTest::IndexConversionPerfTest()
: ANGLERenderTest("IndexConversionPerfTest", GetParam()),
mProgram(0),
mVertexBuffer(0),
mIndexBuffer(0)
{
mRunTimeSeconds = 3.0;
}
void IndexConversionPerfTest::initializeBenchmark()
{
const auto ¶ms = GetParam();
ASSERT_LT(0u, params.iterations);
ASSERT_LT(0u, params.numIndexTris);
const std::string vs = SHADER_SOURCE
(
attribute vec2 vPosition;
uniform float uScale;
uniform float uOffset;
void main()
{
gl_Position = vec4(vPosition * vec2(uScale) - vec2(uOffset), 0, 1);
}
);
const std::string fs = SHADER_SOURCE
(
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
);
mProgram = CompileProgram(vs, fs);
ASSERT_NE(0u, mProgram);
// Use the program object
glUseProgram(mProgram);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Initialize the vertex data
std::vector<GLfloat> floatData;
size_t numTris = std::numeric_limits<GLushort>::max() / 3 + 1;
for (size_t triIndex = 0; triIndex < numTris; ++triIndex)
{
floatData.push_back(1);
floatData.push_back(2);
floatData.push_back(0);
floatData.push_back(0);
floatData.push_back(2);
floatData.push_back(0);
}
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, floatData.size() * sizeof(GLfloat), &floatData[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// Initialize the index buffer
for (unsigned int triIndex = 0; triIndex < params.numIndexTris; ++triIndex)
{
mIndexData.push_back(std::numeric_limits<GLushort>::max());
mIndexData.push_back(1);
mIndexData.push_back(2);
}
glGenBuffers(1, &mIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
updateBufferData();
// Set the viewport
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
GLfloat scale = 0.5f;
GLfloat offset = 0.5f;
glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
ASSERT_GL_NO_ERROR();
}
void IndexConversionPerfTest::updateBufferData()
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexData.size() * sizeof(mIndexData[0]), &mIndexData[0], GL_STATIC_DRAW);
}
void IndexConversionPerfTest::destroyBenchmark()
{
glDeleteProgram(mProgram);
glDeleteBuffers(1, &mVertexBuffer);
glDeleteBuffers(1, &mIndexBuffer);
}
void IndexConversionPerfTest::drawBenchmark()
{
glClear(GL_COLOR_BUFFER_BIT);
const auto ¶ms = GetParam();
// Trigger an update to ensure we convert once a frame
updateBufferData();
for (unsigned int it = 0; it < params.iterations; it++)
{
glDrawElements(GL_TRIANGLES,
static_cast<GLsizei>(params.numIndexTris * 3 - 1),
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(0));
}
ASSERT_GL_NO_ERROR();
}
IndexConversionPerfParams IndexConversionPerfD3D11Params()
{
IndexConversionPerfParams params;
params.eglParameters = egl_platform::D3D11_NULL();
params.majorVersion = 2;
params.minorVersion = 0;
params.windowWidth = 256;
params.windowHeight = 256;
params.iterations = 225;
params.numIndexTris = 3000;
return params;
}
TEST_P(IndexConversionPerfTest, Run)
{
run();
}
ANGLE_INSTANTIATE_TEST(IndexConversionPerfTest,
IndexConversionPerfD3D11Params());
} // namespace