1 //
2 // Copyright 2019 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 // ClearPerf:
7 // Performance test for clearing framebuffers.
8 //
9
10 #include "ANGLEPerfTest.h"
11
12 #include <iostream>
13 #include <random>
14 #include <sstream>
15
16 #include "test_utils/gl_raii.h"
17 #include "util/shader_utils.h"
18
19 using namespace angle;
20
21 namespace
22 {
23 constexpr unsigned int kIterationsPerStep = 256;
24
25 struct ClearParams final : public RenderTestParams
26 {
ClearParams__anon4c3758da0111::ClearParams27 ClearParams()
28 {
29 iterationsPerStep = kIterationsPerStep;
30 trackGpuTime = true;
31
32 fboSize = 2048;
33 textureSize = 16;
34
35 internalFormat = GL_RGBA8;
36 }
37
38 std::string story() const override;
39
40 GLsizei fboSize;
41 GLsizei textureSize;
42
43 GLenum internalFormat;
44 };
45
operator <<(std::ostream & os,const ClearParams & params)46 std::ostream &operator<<(std::ostream &os, const ClearParams ¶ms)
47 {
48 os << params.backendAndStory().substr(1);
49 return os;
50 }
51
story() const52 std::string ClearParams::story() const
53 {
54 std::stringstream strstr;
55
56 strstr << RenderTestParams::story();
57
58 if (internalFormat == GL_RGB8)
59 {
60 strstr << "_rgb";
61 }
62
63 return strstr.str();
64 }
65
66 class ClearBenchmark : public ANGLERenderTest, public ::testing::WithParamInterface<ClearParams>
67 {
68 public:
69 ClearBenchmark();
70
71 void initializeBenchmark() override;
72 void destroyBenchmark() override;
73 void drawBenchmark() override;
74
75 private:
76 void initShaders();
77
78 std::vector<GLuint> mTextures;
79
80 GLuint mProgram;
81 };
82
ClearBenchmark()83 ClearBenchmark::ClearBenchmark() : ANGLERenderTest("Clear", GetParam()), mProgram(0u)
84 {
85 // Crashes on nvidia+d3d11. http://crbug.com/945415
86 if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
87 {
88 mSkipTest = true;
89 }
90 }
91
initializeBenchmark()92 void ClearBenchmark::initializeBenchmark()
93 {
94 initShaders();
95 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
96
97 ASSERT_GL_NO_ERROR();
98 }
99
initShaders()100 void ClearBenchmark::initShaders()
101 {
102 constexpr char kVS[] = R"(void main()
103 {
104 gl_Position = vec4(0, 0, 0, 1);
105 })";
106
107 constexpr char kFS[] = R"(precision mediump float;
108 void main()
109 {
110 gl_FragColor = vec4(0);
111 })";
112
113 mProgram = CompileProgram(kVS, kFS);
114 ASSERT_NE(0u, mProgram);
115
116 glUseProgram(mProgram);
117
118 glDisable(GL_DEPTH_TEST);
119
120 ASSERT_GL_NO_ERROR();
121 }
122
destroyBenchmark()123 void ClearBenchmark::destroyBenchmark()
124 {
125 glDeleteProgram(mProgram);
126 }
127
drawBenchmark()128 void ClearBenchmark::drawBenchmark()
129 {
130 const auto ¶ms = GetParam();
131
132 std::vector<float> textureData(params.textureSize * params.textureSize * 4, 0.5);
133
134 GLRenderbuffer colorRbo;
135 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
136 glRenderbufferStorage(GL_RENDERBUFFER, params.internalFormat, params.fboSize, params.fboSize);
137
138 GLRenderbuffer depthRbo;
139 glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
140 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, params.fboSize, params.fboSize);
141
142 GLFramebuffer fbo;
143 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
144 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
145 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo);
146
147 startGpuTimer();
148 for (size_t it = 0; it < params.iterationsPerStep; ++it)
149 {
150 float clearValue = (it % 2) * 0.5f + 0.2f;
151 glClearColor(clearValue, clearValue, clearValue, clearValue);
152 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
153 glDrawArrays(GL_TRIANGLES, 0, 3);
154 }
155 stopGpuTimer();
156
157 ASSERT_GL_NO_ERROR();
158 }
159
D3D11Params()160 ClearParams D3D11Params()
161 {
162 ClearParams params;
163 params.eglParameters = egl_platform::D3D11();
164 return params;
165 }
166
OpenGLOrGLESParams()167 ClearParams OpenGLOrGLESParams()
168 {
169 ClearParams params;
170 params.eglParameters = egl_platform::OPENGL_OR_GLES();
171 return params;
172 }
173
VulkanParams(bool emulatedFormat)174 ClearParams VulkanParams(bool emulatedFormat)
175 {
176 ClearParams params;
177 params.eglParameters = egl_platform::VULKAN();
178 if (emulatedFormat)
179 {
180 params.internalFormat = GL_RGB8;
181 }
182 return params;
183 }
184
185 } // anonymous namespace
186
TEST_P(ClearBenchmark,Run)187 TEST_P(ClearBenchmark, Run)
188 {
189 run();
190 }
191
192 ANGLE_INSTANTIATE_TEST(ClearBenchmark,
193 D3D11Params(),
194 OpenGLOrGLESParams(),
195 VulkanParams(false),
196 VulkanParams(true));
197