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__anon7c4ebcb30111::ClearParams27 ClearParams()
28 {
29 iterationsPerStep = kIterationsPerStep;
30 trackGpuTime = true;
31
32 fboSize = 2048;
33 textureSize = 16;
34 }
35
36 std::string story() const override;
37
38 GLsizei fboSize;
39 GLsizei textureSize;
40 };
41
operator <<(std::ostream & os,const ClearParams & params)42 std::ostream &operator<<(std::ostream &os, const ClearParams ¶ms)
43 {
44 os << params.backendAndStory().substr(1);
45 return os;
46 }
47
story() const48 std::string ClearParams::story() const
49 {
50 std::stringstream strstr;
51
52 strstr << RenderTestParams::story();
53
54 return strstr.str();
55 }
56
57 class ClearBenchmark : public ANGLERenderTest, public ::testing::WithParamInterface<ClearParams>
58 {
59 public:
60 ClearBenchmark();
61
62 void initializeBenchmark() override;
63 void destroyBenchmark() override;
64 void drawBenchmark() override;
65
66 private:
67 void initShaders();
68
69 std::vector<GLuint> mTextures;
70
71 GLuint mProgram;
72 GLuint mPositionLoc;
73 GLuint mSamplerLoc;
74 };
75
ClearBenchmark()76 ClearBenchmark::ClearBenchmark()
77 : ANGLERenderTest("Clear", GetParam()), mProgram(0u), mPositionLoc(-1), mSamplerLoc(-1)
78 {
79 // Crashes on nvidia+d3d11. http://crbug.com/945415
80 if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
81 {
82 mSkipTest = true;
83 }
84 }
85
initializeBenchmark()86 void ClearBenchmark::initializeBenchmark()
87 {
88 initShaders();
89 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
90 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
91
92 ASSERT_GL_NO_ERROR();
93 }
94
initShaders()95 void ClearBenchmark::initShaders()
96 {
97 constexpr char kVS[] = R"(attribute vec4 a_position;
98 void main()
99 {
100 gl_Position = a_position;
101 })";
102
103 constexpr char kFS[] = R"(precision mediump float;
104 uniform sampler2D s_texture;
105 void main()
106 {
107 gl_FragColor = texture2D(s_texture, vec2(0, 0));
108 })";
109
110 mProgram = CompileProgram(kVS, kFS);
111 ASSERT_NE(0u, mProgram);
112
113 mPositionLoc = glGetAttribLocation(mProgram, "a_position");
114 mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
115 glUseProgram(mProgram);
116
117 glDisable(GL_DEPTH_TEST);
118
119 ASSERT_GL_NO_ERROR();
120 }
121
destroyBenchmark()122 void ClearBenchmark::destroyBenchmark()
123 {
124 glDeleteProgram(mProgram);
125 }
126
drawBenchmark()127 void ClearBenchmark::drawBenchmark()
128 {
129 const auto ¶ms = GetParam();
130
131 std::vector<float> textureData(params.textureSize * params.textureSize * 4, 0.5);
132
133 GLTexture tex;
134
135 glActiveTexture(GL_TEXTURE0);
136 glBindTexture(GL_TEXTURE_2D, tex);
137
138 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params.textureSize, params.textureSize, 0, GL_RGBA,
139 GL_UNSIGNED_BYTE, textureData.data());
140
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
145
146 glUniform1i(mSamplerLoc, 0);
147
148 GLRenderbuffer colorRbo;
149 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
150 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, params.fboSize, params.fboSize);
151
152 GLRenderbuffer depthRbo;
153 glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
154 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, params.fboSize, params.fboSize);
155
156 GLFramebuffer fbo;
157 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
158 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
159 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo);
160
161 startGpuTimer();
162 for (size_t it = 0; it < params.iterationsPerStep; ++it)
163 {
164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
165 glDrawArrays(GL_TRIANGLES, 0, 3);
166 }
167 stopGpuTimer();
168
169 ASSERT_GL_NO_ERROR();
170 }
171
D3D11Params()172 ClearParams D3D11Params()
173 {
174 ClearParams params;
175 params.eglParameters = egl_platform::D3D11();
176 return params;
177 }
178
OpenGLOrGLESParams()179 ClearParams OpenGLOrGLESParams()
180 {
181 ClearParams params;
182 params.eglParameters = egl_platform::OPENGL_OR_GLES();
183 return params;
184 }
185
VulkanParams()186 ClearParams VulkanParams()
187 {
188 ClearParams params;
189 params.eglParameters = egl_platform::VULKAN();
190 return params;
191 }
192
193 } // anonymous namespace
194
TEST_P(ClearBenchmark,Run)195 TEST_P(ClearBenchmark, Run)
196 {
197 run();
198 }
199
200 ANGLE_INSTANTIATE_TEST(ClearBenchmark, D3D11Params(), OpenGLOrGLESParams(), VulkanParams());
201