1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // DynamicPromotionPerfTest:
7*8975f5c5SAndroid Build Coastguard Worker // Tests that ANGLE will promote buffer specfied with DYNAMIC usage to static after a number of
8*8975f5c5SAndroid Build Coastguard Worker // iterations without changing the data. It specifically affects the D3D back-end, which treats
9*8975f5c5SAndroid Build Coastguard Worker // dynamic and static buffers quite differently.
10*8975f5c5SAndroid Build Coastguard Worker //
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/vector_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker
17*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker constexpr unsigned int kIterationsPerStep = 4;
22*8975f5c5SAndroid Build Coastguard Worker
23*8975f5c5SAndroid Build Coastguard Worker struct DynamicPromotionParams final : public RenderTestParams
24*8975f5c5SAndroid Build Coastguard Worker {
DynamicPromotionParams__anon2afabc4e0111::DynamicPromotionParams25*8975f5c5SAndroid Build Coastguard Worker DynamicPromotionParams() { iterationsPerStep = kIterationsPerStep; }
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker std::string story() const override;
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Worker size_t vertexCount = 1024;
30*8975f5c5SAndroid Build Coastguard Worker };
31*8975f5c5SAndroid Build Coastguard Worker
story() const32*8975f5c5SAndroid Build Coastguard Worker std::string DynamicPromotionParams::story() const
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker return RenderTestParams::story();
35*8975f5c5SAndroid Build Coastguard Worker }
36*8975f5c5SAndroid Build Coastguard Worker
operator <<(std::ostream & os,const DynamicPromotionParams & params)37*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &os, const DynamicPromotionParams ¶ms)
38*8975f5c5SAndroid Build Coastguard Worker {
39*8975f5c5SAndroid Build Coastguard Worker os << params.backendAndStory().substr(1);
40*8975f5c5SAndroid Build Coastguard Worker return os;
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker class DynamicPromotionPerfTest : public ANGLERenderTest,
44*8975f5c5SAndroid Build Coastguard Worker public testing::WithParamInterface<DynamicPromotionParams>
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker public:
47*8975f5c5SAndroid Build Coastguard Worker DynamicPromotionPerfTest();
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker void initializeBenchmark() override;
50*8975f5c5SAndroid Build Coastguard Worker void destroyBenchmark() override;
51*8975f5c5SAndroid Build Coastguard Worker void drawBenchmark() override;
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker private:
54*8975f5c5SAndroid Build Coastguard Worker GLuint mProgram;
55*8975f5c5SAndroid Build Coastguard Worker GLuint mElementArrayBuffer;
56*8975f5c5SAndroid Build Coastguard Worker GLuint mArrayBuffer;
57*8975f5c5SAndroid Build Coastguard Worker };
58*8975f5c5SAndroid Build Coastguard Worker
DynamicPromotionPerfTest()59*8975f5c5SAndroid Build Coastguard Worker DynamicPromotionPerfTest::DynamicPromotionPerfTest()
60*8975f5c5SAndroid Build Coastguard Worker : ANGLERenderTest("DynamicPromotion", GetParam()),
61*8975f5c5SAndroid Build Coastguard Worker mProgram(0),
62*8975f5c5SAndroid Build Coastguard Worker mElementArrayBuffer(0),
63*8975f5c5SAndroid Build Coastguard Worker mArrayBuffer(0)
64*8975f5c5SAndroid Build Coastguard Worker {}
65*8975f5c5SAndroid Build Coastguard Worker
initializeBenchmark()66*8975f5c5SAndroid Build Coastguard Worker void DynamicPromotionPerfTest::initializeBenchmark()
67*8975f5c5SAndroid Build Coastguard Worker {
68*8975f5c5SAndroid Build Coastguard Worker constexpr char kVertexShaderSource[] =
69*8975f5c5SAndroid Build Coastguard Worker "attribute vec2 position;\n"
70*8975f5c5SAndroid Build Coastguard Worker "attribute vec3 color;\n"
71*8975f5c5SAndroid Build Coastguard Worker "varying vec3 vColor;\n"
72*8975f5c5SAndroid Build Coastguard Worker "void main()\n"
73*8975f5c5SAndroid Build Coastguard Worker "{\n"
74*8975f5c5SAndroid Build Coastguard Worker " vColor = color;\n"
75*8975f5c5SAndroid Build Coastguard Worker " gl_Position = vec4(position, 0, 1);\n"
76*8975f5c5SAndroid Build Coastguard Worker "}";
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker constexpr char kFragmentShaderSource[] =
79*8975f5c5SAndroid Build Coastguard Worker "varying mediump vec3 vColor;\n"
80*8975f5c5SAndroid Build Coastguard Worker "void main()\n"
81*8975f5c5SAndroid Build Coastguard Worker "{\n"
82*8975f5c5SAndroid Build Coastguard Worker " gl_FragColor = vec4(vColor, 1);\n"
83*8975f5c5SAndroid Build Coastguard Worker "}";
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker mProgram = CompileProgram(kVertexShaderSource, kFragmentShaderSource);
86*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(0u, mProgram);
87*8975f5c5SAndroid Build Coastguard Worker
88*8975f5c5SAndroid Build Coastguard Worker const size_t vertexCount = GetParam().vertexCount;
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker std::vector<GLushort> indexData;
91*8975f5c5SAndroid Build Coastguard Worker std::vector<Vector2> positionData;
92*8975f5c5SAndroid Build Coastguard Worker std::vector<Vector3> colorData;
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker ASSERT_GE(static_cast<size_t>(std::numeric_limits<GLushort>::max()), vertexCount);
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker RNG rng(1);
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < vertexCount; ++index)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker indexData.push_back(static_cast<GLushort>(index));
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker Vector2 position(rng.randomNegativeOneToOne(), rng.randomNegativeOneToOne());
103*8975f5c5SAndroid Build Coastguard Worker positionData.push_back(position);
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker Vector3 color(rng.randomFloat(), rng.randomFloat(), rng.randomFloat());
106*8975f5c5SAndroid Build Coastguard Worker colorData.push_back(color);
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker glGenBuffers(1, &mElementArrayBuffer);
110*8975f5c5SAndroid Build Coastguard Worker glGenBuffers(1, &mArrayBuffer);
111*8975f5c5SAndroid Build Coastguard Worker
112*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementArrayBuffer);
113*8975f5c5SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, mArrayBuffer);
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr elementArraySize = sizeof(GLushort) * vertexCount;
116*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr positionArraySize = sizeof(Vector2) * vertexCount;
117*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr colorArraySize = sizeof(Vector3) * vertexCount;
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker // The DYNAMIC_DRAW usage is the key to the test.
120*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementArraySize, indexData.data(), GL_DYNAMIC_DRAW);
121*8975f5c5SAndroid Build Coastguard Worker glBufferData(GL_ARRAY_BUFFER, positionArraySize + colorArraySize, nullptr, GL_DYNAMIC_DRAW);
122*8975f5c5SAndroid Build Coastguard Worker glBufferSubData(GL_ARRAY_BUFFER, 0, positionArraySize, positionData.data());
123*8975f5c5SAndroid Build Coastguard Worker glBufferSubData(GL_ARRAY_BUFFER, positionArraySize, colorArraySize, colorData.data());
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker glUseProgram(mProgram);
126*8975f5c5SAndroid Build Coastguard Worker GLint positionLocation = glGetAttribLocation(mProgram, "position");
127*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, positionLocation);
128*8975f5c5SAndroid Build Coastguard Worker GLint colorLocation = glGetAttribLocation(mProgram, "color");
129*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(-1, colorLocation);
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
132*8975f5c5SAndroid Build Coastguard Worker glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 0,
133*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<const void *>(positionArraySize));
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(positionLocation);
136*8975f5c5SAndroid Build Coastguard Worker glEnableVertexAttribArray(colorLocation);
137*8975f5c5SAndroid Build Coastguard Worker
138*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker
destroyBenchmark()141*8975f5c5SAndroid Build Coastguard Worker void DynamicPromotionPerfTest::destroyBenchmark()
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker glDeleteProgram(mProgram);
144*8975f5c5SAndroid Build Coastguard Worker glDeleteBuffers(1, &mElementArrayBuffer);
145*8975f5c5SAndroid Build Coastguard Worker glDeleteBuffers(1, &mArrayBuffer);
146*8975f5c5SAndroid Build Coastguard Worker }
147*8975f5c5SAndroid Build Coastguard Worker
drawBenchmark()148*8975f5c5SAndroid Build Coastguard Worker void DynamicPromotionPerfTest::drawBenchmark()
149*8975f5c5SAndroid Build Coastguard Worker {
150*8975f5c5SAndroid Build Coastguard Worker unsigned int iterations = GetParam().iterationsPerStep;
151*8975f5c5SAndroid Build Coastguard Worker size_t vertexCount = GetParam().vertexCount;
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
154*8975f5c5SAndroid Build Coastguard Worker for (unsigned int count = 0; count < iterations; ++count)
155*8975f5c5SAndroid Build Coastguard Worker {
156*8975f5c5SAndroid Build Coastguard Worker glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(vertexCount), GL_UNSIGNED_SHORT, nullptr);
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker
159*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker
DynamicPromotionD3D11Params()162*8975f5c5SAndroid Build Coastguard Worker DynamicPromotionParams DynamicPromotionD3D11Params()
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker DynamicPromotionParams params;
165*8975f5c5SAndroid Build Coastguard Worker params.eglParameters = egl_platform::D3D11();
166*8975f5c5SAndroid Build Coastguard Worker return params;
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker
TEST_P(DynamicPromotionPerfTest,Run)169*8975f5c5SAndroid Build Coastguard Worker TEST_P(DynamicPromotionPerfTest, Run)
170*8975f5c5SAndroid Build Coastguard Worker {
171*8975f5c5SAndroid Build Coastguard Worker run();
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker
174*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST(DynamicPromotionPerfTest, DynamicPromotionD3D11Params());
175*8975f5c5SAndroid Build Coastguard Worker
176*8975f5c5SAndroid Build Coastguard Worker // This test suite is not instantiated on some OSes.
177*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicPromotionPerfTest);
178*8975f5c5SAndroid Build Coastguard Worker
179*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
180