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