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