xref: /aosp_15_r20/external/angle/src/tests/perf_tests/ClearPerf.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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/ANGLETest.h"
17 #include "test_utils/gl_raii.h"
18 #include "util/random_utils.h"
19 #include "util/shader_utils.h"
20 
21 using namespace angle;
22 
23 namespace
24 {
25 constexpr unsigned int kIterationsPerStep = 256;
26 
27 struct ClearParams final : public RenderTestParams
28 {
ClearParams__anon23f243090111::ClearParams29     ClearParams()
30     {
31         iterationsPerStep = kIterationsPerStep;
32         trackGpuTime      = true;
33 
34         fboSize = 2048;
35 
36         internalFormat = GL_RGBA8;
37 
38         scissoredClear = false;
39     }
40 
41     std::string story() const override;
42 
43     GLsizei fboSize;
44     GLsizei textureSize;
45 
46     GLenum internalFormat;
47 
48     bool scissoredClear;
49 };
50 
operator <<(std::ostream & os,const ClearParams & params)51 std::ostream &operator<<(std::ostream &os, const ClearParams &params)
52 {
53     os << params.backendAndStory().substr(1);
54     return os;
55 }
56 
story() const57 std::string ClearParams::story() const
58 {
59     std::stringstream strstr;
60 
61     strstr << RenderTestParams::story();
62 
63     if (internalFormat == GL_RGB8)
64     {
65         strstr << "_rgb";
66     }
67 
68     if (scissoredClear)
69     {
70         strstr << "_scissoredClear";
71     }
72 
73     return strstr.str();
74 }
75 
76 class ClearBenchmark : public ANGLERenderTest, public ::testing::WithParamInterface<ClearParams>
77 {
78   public:
79     ClearBenchmark();
80 
81     void initializeBenchmark() override;
82     void destroyBenchmark() override;
83     void drawBenchmark() override;
84 
85   private:
86     void initShaders();
87 
88     std::vector<GLuint> mTextures;
89 
90     GLuint mProgram;
91 };
92 
ClearBenchmark()93 ClearBenchmark::ClearBenchmark() : ANGLERenderTest("Clear", GetParam()), mProgram(0u)
94 {
95     if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
96     {
97         skipTest("http://crbug.com/945415 Crashes on nvidia+d3d11");
98     }
99 }
100 
initializeBenchmark()101 void ClearBenchmark::initializeBenchmark()
102 {
103     initShaders();
104     glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
105 
106     ASSERT_GL_NO_ERROR();
107 }
108 
initShaders()109 void ClearBenchmark::initShaders()
110 {
111     constexpr char kVS[] = R"(void main()
112 {
113     gl_Position = vec4(0, 0, 0, 1);
114 })";
115 
116     constexpr char kFS[] = R"(precision mediump float;
117 void main()
118 {
119     gl_FragColor = vec4(0);
120 })";
121 
122     mProgram = CompileProgram(kVS, kFS);
123     ASSERT_NE(0u, mProgram);
124 
125     glUseProgram(mProgram);
126 
127     glDisable(GL_DEPTH_TEST);
128 
129     ASSERT_GL_NO_ERROR();
130 }
131 
destroyBenchmark()132 void ClearBenchmark::destroyBenchmark()
133 {
134     glDeleteProgram(mProgram);
135 }
136 
drawBenchmark()137 void ClearBenchmark::drawBenchmark()
138 {
139     const auto &params = GetParam();
140 
141     GLRenderbuffer colorRbo;
142     glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
143     glRenderbufferStorage(GL_RENDERBUFFER, params.internalFormat, params.fboSize, params.fboSize);
144 
145     GLRenderbuffer depthRbo;
146     glBindRenderbuffer(GL_RENDERBUFFER, depthRbo);
147     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, params.fboSize, params.fboSize);
148 
149     GLFramebuffer fbo;
150     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
151     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
152     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo);
153 
154     glViewport(0, 0, params.fboSize, params.fboSize);
155     glDisable(GL_SCISSOR_TEST);
156 
157     startGpuTimer();
158 
159     if (params.scissoredClear)
160     {
161         angle::RNG rng;
162         const GLuint width  = params.fboSize;
163         const GLuint height = params.fboSize;
164         for (GLuint index = 0; index < (width - 1) / 2; index++)
165         {
166             // Do the first clear without the scissor.
167             if (index > 0)
168             {
169                 glEnable(GL_SCISSOR_TEST);
170                 glScissor(index, index, width - (index * 2), height - (index * 2));
171             }
172 
173             GLColor color      = RandomColor(&rng);
174             Vector4 floatColor = color.toNormalizedVector();
175             glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
176             glClear(GL_COLOR_BUFFER_BIT);
177         }
178     }
179     else
180     {
181         for (size_t it = 0; it < params.iterationsPerStep; ++it)
182         {
183             float clearValue = (it % 2) * 0.5f + 0.2f;
184             glClearColor(clearValue, clearValue, clearValue, clearValue);
185             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
186             glDrawArrays(GL_TRIANGLES, 0, 3);
187         }
188     }
189 
190     stopGpuTimer();
191 
192     ASSERT_GL_NO_ERROR();
193 }
194 
D3D11Params()195 ClearParams D3D11Params()
196 {
197     ClearParams params;
198     params.eglParameters = egl_platform::D3D11();
199     return params;
200 }
201 
MetalParams()202 ClearParams MetalParams()
203 {
204     ClearParams params;
205     params.eglParameters = egl_platform::METAL();
206     return params;
207 }
208 
OpenGLOrGLESParams()209 ClearParams OpenGLOrGLESParams()
210 {
211     ClearParams params;
212     params.eglParameters = egl_platform::OPENGL_OR_GLES();
213     return params;
214 }
215 
VulkanParams(bool emulatedFormat,bool scissoredClear)216 ClearParams VulkanParams(bool emulatedFormat, bool scissoredClear)
217 {
218     ClearParams params;
219     params.eglParameters = egl_platform::VULKAN();
220     if (emulatedFormat)
221     {
222         params.internalFormat = GL_RGB8;
223     }
224     params.scissoredClear = scissoredClear;
225     return params;
226 }
227 
228 }  // anonymous namespace
229 
TEST_P(ClearBenchmark,Run)230 TEST_P(ClearBenchmark, Run)
231 {
232     run();
233 }
234 
235 ANGLE_INSTANTIATE_TEST(ClearBenchmark,
236                        D3D11Params(),
237                        MetalParams(),
238                        OpenGLOrGLESParams(),
239                        VulkanParams(false, false),
240                        VulkanParams(true, false),
241                        VulkanParams(false, true));
242