xref: /aosp_15_r20/external/deqp/modules/gles3/stress/es3sLongRunningTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Long-running stress tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3sLongRunningTests.hpp"
25 #include "glsLongStressCase.hpp"
26 #include "glsLongStressTestUtil.hpp"
27 #include "glwEnums.hpp"
28 
29 #include <string>
30 
31 using std::string;
32 
33 namespace deqp
34 {
35 namespace gles3
36 {
37 namespace Stress
38 {
39 
LongRunningTests(Context & context)40 LongRunningTests::LongRunningTests(Context &context) : TestCaseGroup(context, "long", "Long-running stress tests")
41 {
42 }
43 
~LongRunningTests(void)44 LongRunningTests::~LongRunningTests(void)
45 {
46 }
47 
init(void)48 void LongRunningTests::init(void)
49 {
50     static const int Mi = 1 << 20;
51     const gls::LongStressTestUtil::ProgramLibrary progLib(glu::GLSL_VERSION_300_ES);
52 
53     typedef gls::LongStressCase::FeatureProbabilities Probs;
54 
55     // Buffer cases.
56 
57     {
58         static const struct MemCase
59         {
60             const char *const nameSuffix;
61             const char *const descSuffix;
62             const int limit;
63             const int redundantBufferFactor;
64             MemCase(const char *n, const char *d, int l, int r)
65                 : nameSuffix(n)
66                 , descSuffix(d)
67                 , limit(l)
68                 , redundantBufferFactor(r)
69             {
70             }
71         } memoryLimitCases[] = {MemCase("_low_memory", "; use a low buffer memory usage limit", 8 * Mi, 2),
72                                 MemCase("_high_memory", "; use a high buffer memory usage limit", 256 * Mi, 64)};
73 
74         const std::vector<gls::ProgramContext> contexts(1, progLib.generateBufferContext(4));
75 
76         static const struct Case
77         {
78             const char *const name;
79             const char *const desc;
80             const int redundantBufferFactor; //!< If non-positive, taken from memoryLimitCases.
81             const Probs probs;
82             Case(const char *const name_, const char *const desc_, int bufFact, const Probs &probs_ = Probs())
83                 : name(name_)
84                 , desc(desc_)
85                 , redundantBufferFactor(bufFact)
86                 , probs(probs_)
87             {
88             }
89         } cases[] = {Case("always_reupload", "Re-upload buffer data at the beginning of each iteration", -1,
90                           Probs().pReuploadBuffer(1.0f)),
91 
92                      Case("always_reupload_bufferdata",
93                           "Re-upload buffer data at the beginning of each iteration, using glBufferData", -1,
94                           Probs().pReuploadBuffer(1.0f).pReuploadWithBufferData(1.0f)),
95 
96                      Case("always_delete",
97                           "Delete buffers at the end of each iteration, and re-create at the beginning of the next", -1,
98                           Probs().pDeleteBuffer(1.0f)),
99 
100                      Case("wasteful", "Don't reuse buffers, and only delete them when given memory limit is reached", 2,
101                           Probs().pWastefulBufferMemoryUsage(1.0f)),
102 
103                      Case("separate_attribute_buffers_wasteful", "Give each vertex attribute its own buffer", 2,
104                           Probs().pSeparateAttribBuffers(1.0f).pWastefulBufferMemoryUsage(1.0f))};
105 
106         TestCaseGroup *const bufferGroup = new TestCaseGroup(m_context, "buffer", "Buffer stress tests");
107         addChild(bufferGroup);
108 
109         for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
110         {
111             for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
112             {
113                 const int redundantBufferFactor = cases[caseNdx].redundantBufferFactor > 0 ?
114                                                       cases[caseNdx].redundantBufferFactor :
115                                                       memoryLimitCases[memoryLimitNdx].redundantBufferFactor;
116 
117                 bufferGroup->addChild(new gls::LongStressCase(
118                     m_context.getTestContext(), m_context.getRenderContext(),
119                     (string() + cases[caseNdx].name + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
120                     (string() + cases[caseNdx].desc + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
121                     0 /* tex memory */, memoryLimitCases[memoryLimitNdx].limit, 1 /* draw calls per iteration */,
122                     50000 /* tris per call */, contexts, cases[caseNdx].probs, GL_DYNAMIC_DRAW, GL_DYNAMIC_DRAW,
123                     redundantBufferFactor));
124             }
125         }
126     }
127 
128     // Texture cases.
129 
130     {
131         static const struct MemCase
132         {
133             const char *const nameSuffix;
134             const char *const descSuffix;
135             const int limit;
136             const int numTextures;
137             MemCase(const char *n, const char *d, int l, int t) : nameSuffix(n), descSuffix(d), limit(l), numTextures(t)
138             {
139             }
140         } memoryLimitCases[] = {MemCase("_low_memory", "; use a low texture memory usage limit", 8 * Mi, 6),
141                                 MemCase("_high_memory", "; use a high texture memory usage limit", 256 * Mi, 192)};
142 
143         static const struct Case
144         {
145             const char *const name;
146             const char *const desc;
147             const int numTextures; //!< If non-positive, taken from memoryLimitCases.
148             const Probs probs;
149             Case(const char *const name_, const char *const desc_, int numTextures_, const Probs &probs_ = Probs())
150                 : name(name_)
151                 , desc(desc_)
152                 , numTextures(numTextures_)
153                 , probs(probs_)
154             {
155             }
156         } cases[] = {Case("always_reupload", "Re-upload texture data at the beginning of each iteration", -1,
157                           Probs().pReuploadTexture(1.0f)),
158 
159                      Case("always_reupload_teximage",
160                           "Re-upload texture data at the beginning of each iteration, using glTexImage*", -1,
161                           Probs().pReuploadTexture(1.0f).pReuploadWithTexImage(1.0f)),
162 
163                      Case("always_delete",
164                           "Delete textures at the end of each iteration, and re-create at the beginning of the next",
165                           -1, Probs().pDeleteTexture(1.0f)),
166 
167                      Case("wasteful", "Don't reuse textures, and only delete them when given memory limit is reached",
168                           6, Probs().pWastefulTextureMemoryUsage(1.0f))};
169 
170         TestCaseGroup *const textureGroup = new TestCaseGroup(m_context, "texture", "Texture stress tests");
171         addChild(textureGroup);
172 
173         for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
174         {
175             for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
176             {
177                 const int numTextures = cases[caseNdx].numTextures > 0 ? cases[caseNdx].numTextures :
178                                                                          memoryLimitCases[memoryLimitNdx].numTextures;
179                 const std::vector<gls::ProgramContext> contexts(
180                     1, progLib.generateTextureContext(numTextures, 512, 512, 0.1f));
181 
182                 textureGroup->addChild(new gls::LongStressCase(
183                     m_context.getTestContext(), m_context.getRenderContext(),
184                     (string() + cases[caseNdx].name + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
185                     (string() + cases[caseNdx].desc + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
186                     memoryLimitCases[memoryLimitNdx].limit, 1 * Mi /* buf memory */, 1 /* draw calls per iteration */,
187                     10000 /* tris per call */, contexts, cases[caseNdx].probs, GL_STATIC_DRAW, GL_STATIC_DRAW));
188             }
189         }
190     }
191 
192     // Draw call cases.
193 
194     {
195         const std::vector<gls::ProgramContext> contexts(1, progLib.generateTextureContext(1, 128, 128, 0.5f));
196 
197         static const struct Case
198         {
199             const char *const name;
200             const char *const desc;
201             const int drawCallsPerIteration;
202             const int numTrisPerDrawCall;
203             const Probs probs;
204             Case(const char *const name_, const char *const desc_, const int calls, const int tris,
205                  const Probs &probs_ = Probs())
206                 : name(name_)
207                 , desc(desc_)
208                 , drawCallsPerIteration(calls)
209                 , numTrisPerDrawCall(tris)
210                 , probs(probs_)
211             {
212             }
213         } cases[] = {Case("client_memory_data", "Use client-memory for index and attribute data, instead of GL buffers",
214                           200, 500, Probs().pClientMemoryAttributeData(1.0f).pClientMemoryIndexData(1.0f)),
215 
216                      Case("vary_draw_function",
217                           "Choose between glDrawElements and glDrawArrays each iteration, with uniform probability",
218                           200, 500, Probs().pUseDrawArrays(0.5f)),
219 
220                      Case("few_big_calls", "Per iteration, do a few draw calls with a big number of triangles per call",
221                           2, 50000),
222 
223                      Case("many_small_calls",
224                           "Per iteration, do many draw calls with a small number of triangles per call", 2000, 50)};
225 
226         TestCaseGroup *const drawCallGroup = new TestCaseGroup(m_context, "draw_call", "Draw call stress tests");
227         addChild(drawCallGroup);
228 
229         for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
230         {
231             drawCallGroup->addChild(new gls::LongStressCase(
232                 m_context.getTestContext(), m_context.getRenderContext(), cases[caseNdx].name, cases[caseNdx].desc,
233                 1 * Mi /* tex memory */, 2 * Mi /* buf memory */, cases[caseNdx].drawCallsPerIteration,
234                 cases[caseNdx].numTrisPerDrawCall, contexts, cases[caseNdx].probs, GL_STATIC_DRAW, GL_STATIC_DRAW));
235         }
236     }
237 
238     // Shader cases.
239 
240     {
241         std::vector<gls::ProgramContext> contexts;
242         contexts.push_back(progLib.generateFragmentPointLightContext(512, 512));
243         contexts.push_back(progLib.generateVertexUniformLoopLightContext(512, 512));
244 
245         static const struct Case
246         {
247             const char *const name;
248             const char *const desc;
249             const Probs probs;
250             Case(const char *const name_, const char *const desc_, const Probs &probs_ = Probs())
251                 : name(name_)
252                 , desc(desc_)
253                 , probs(probs_)
254             {
255             }
256         } cases[] = {Case("several_programs",
257                           "Use several different programs, choosing between them uniformly on each iteration"),
258 
259                      Case("several_programs_always_rebuild",
260                           "Use several different programs, choosing between them uniformly on each iteration, and "
261                           "always rebuild the program",
262                           Probs().pRebuildProgram(1.0f))};
263 
264         TestCaseGroup *const shaderGroup = new TestCaseGroup(m_context, "program", "Shader program stress tests");
265         addChild(shaderGroup);
266 
267         for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
268         {
269             shaderGroup->addChild(new gls::LongStressCase(
270                 m_context.getTestContext(), m_context.getRenderContext(), cases[caseNdx].name, cases[caseNdx].desc,
271                 3 * Mi /* tex memory */, 1 * Mi /* buf memory */, 1 /* draw calls per iteration */,
272                 10000 /* tris per call */, contexts, cases[caseNdx].probs, GL_STATIC_DRAW, GL_STATIC_DRAW));
273         }
274     }
275 
276     // Mixed cases.
277 
278     {
279         static const struct MemCase
280         {
281             const char *const nameSuffix;
282             const char *const descSuffix;
283             const int texLimit;
284             const int bufLimit;
285             MemCase(const char *n, const char *d, int t, int b) : nameSuffix(n), descSuffix(d), texLimit(t), bufLimit(b)
286             {
287             }
288         } memoryLimitCases[] = {MemCase("_low_memory", "; use a low memory usage limit", 8 * Mi, 8 * Mi),
289                                 MemCase("_high_memory", "; use a high memory usage limit", 128 * Mi, 128 * Mi)};
290 
291         TestCaseGroup *const mixedGroup = new TestCaseGroup(m_context, "mixed", "Mixed stress tests");
292         addChild(mixedGroup);
293 
294         for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
295         {
296             mixedGroup->addChild(new gls::LongStressCase(
297                 m_context.getTestContext(), m_context.getRenderContext(),
298                 (string() + "buffer_texture_wasteful" + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
299                 (string() + "Use both buffers and textures wastefully" + memoryLimitCases[memoryLimitNdx].descSuffix)
300                     .c_str(),
301                 memoryLimitCases[memoryLimitNdx].texLimit, memoryLimitCases[memoryLimitNdx].bufLimit,
302                 1 /* draw calls per iteration */, 10000 /* tris per call */,
303                 std::vector<gls::ProgramContext>(1, progLib.generateBufferAndTextureContext(4, 512, 512)),
304                 Probs()
305                     .pReuploadTexture(0.3f)
306                     .pReuploadWithTexImage(0.5f)
307                     .pReuploadBuffer(0.3f)
308                     .pReuploadWithBufferData(0.5f)
309                     .pDeleteTexture(0.2f)
310                     .pDeleteBuffer(0.2f)
311                     .pWastefulTextureMemoryUsage(0.5f)
312                     .pWastefulBufferMemoryUsage(0.5f)
313                     .pRandomBufferUploadTarget(1.0f)
314                     .pRandomBufferUsage(1.0f),
315                 GL_STATIC_DRAW, GL_STATIC_DRAW));
316 
317             {
318                 std::vector<gls::ProgramContext> contexts;
319                 contexts.push_back(progLib.generateFragmentPointLightContext(512, 512));
320                 contexts.push_back(progLib.generateVertexUniformLoopLightContext(512, 512));
321                 mixedGroup->addChild(new gls::LongStressCase(
322                     m_context.getTestContext(), m_context.getRenderContext(),
323                     (string() + "random" + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
324                     (string() + "Highly random behavior" + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
325                     memoryLimitCases[memoryLimitNdx].texLimit, memoryLimitCases[memoryLimitNdx].bufLimit,
326                     1 /* draw calls per iteration */, 10000 /* tris per call */, contexts,
327                     Probs()
328                         .pRebuildProgram(0.3f)
329                         .pReuploadTexture(0.3f)
330                         .pReuploadWithTexImage(0.3f)
331                         .pReuploadBuffer(0.3f)
332                         .pReuploadWithBufferData(0.3f)
333                         .pDeleteTexture(0.2f)
334                         .pDeleteBuffer(0.2f)
335                         .pWastefulTextureMemoryUsage(0.3f)
336                         .pWastefulBufferMemoryUsage(0.3f)
337                         .pClientMemoryAttributeData(0.2f)
338                         .pClientMemoryIndexData(0.2f)
339                         .pSeparateAttribBuffers(0.4f)
340                         .pUseDrawArrays(0.4f)
341                         .pRandomBufferUploadTarget(1.0f)
342                         .pRandomBufferUsage(1.0f),
343                     GL_STATIC_DRAW, GL_STATIC_DRAW));
344             }
345         }
346     }
347 }
348 
349 } // namespace Stress
350 } // namespace gles3
351 } // namespace deqp
352