1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Long-running stress tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es2sLongRunningTests.hpp"
25 #include "glsLongStressCase.hpp"
26 #include "glsLongStressTestUtil.hpp"
27 #include "glwEnums.hpp"
40 LongRunningTests::LongRunningTests (Context& context)
41 : TestCaseGroup(context, "long", "Long-running stress tests")
45 LongRunningTests::~LongRunningTests (void)
49 void LongRunningTests::init (void)
51 static const int Mi = 1<<20;
52 const gls::LongStressTestUtil::ProgramLibrary progLib (glu::GLSL_VERSION_100_ES);
54 typedef gls::LongStressCase::FeatureProbabilities Probs;
59 static const struct MemCase
61 const char* const nameSuffix;
62 const char* const descSuffix;
64 const int redundantBufferFactor;
65 MemCase (const char* n, const char* d, int l, int r) : nameSuffix(n), descSuffix(d), limit(l), redundantBufferFactor(r) {}
66 } memoryLimitCases[] =
68 MemCase("_low_memory", "; use a low buffer memory usage limit", 8*Mi, 2),
69 MemCase("_high_memory", "; use a high buffer memory usage limit", 256*Mi, 64)
72 const std::vector<gls::ProgramContext> contexts(1, progLib.generateBufferContext(4));
74 static const struct Case
76 const char* const name;
77 const char* const desc;
78 const int redundantBufferFactor; //!< If non-positive, taken from memoryLimitCases.
80 Case (const char* const name_, const char* const desc_, int bufFact, const Probs& probs_ = Probs()) : name(name_), desc(desc_), redundantBufferFactor(bufFact), probs(probs_) {}
83 Case("always_reupload",
84 "Re-upload buffer data at the beginning of each iteration",
86 Probs().pReuploadBuffer(1.0f)),
88 Case("always_reupload_bufferdata",
89 "Re-upload buffer data at the beginning of each iteration, using glBufferData",
91 Probs().pReuploadBuffer(1.0f).pReuploadWithBufferData(1.0f)),
94 "Delete buffers at the end of each iteration, and re-create at the beginning of the next",
96 Probs().pDeleteBuffer(1.0f)),
99 "Don't reuse buffers, and only delete them when given memory limit is reached",
101 Probs().pWastefulBufferMemoryUsage(1.0f)),
103 Case("separate_attribute_buffers_wasteful",
104 "Give each vertex attribute its own buffer",
106 Probs().pSeparateAttribBuffers(1.0f).pWastefulBufferMemoryUsage(1.0f))
109 TestCaseGroup* const bufferGroup = new TestCaseGroup(m_context, "buffer", "Buffer stress tests");
110 addChild(bufferGroup);
112 for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
114 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
116 const int redundantBufferFactor = cases[caseNdx].redundantBufferFactor > 0 ? cases[caseNdx].redundantBufferFactor : memoryLimitCases[memoryLimitNdx].redundantBufferFactor;
118 bufferGroup->addChild(new gls::LongStressCase(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,
122 1 /* draw calls per iteration */, 50000 /* tris per call */,
123 contexts, cases[caseNdx].probs,
124 GL_DYNAMIC_DRAW, GL_DYNAMIC_DRAW,
125 redundantBufferFactor));
133 static const struct MemCase
135 const char* const nameSuffix;
136 const char* const descSuffix;
138 const int numTextures;
139 MemCase (const char* n, const char* d, int l, int t) : nameSuffix(n), descSuffix(d), limit(l), numTextures(t) {}
140 } memoryLimitCases[] =
142 MemCase("_low_memory", "; use a low texture memory usage limit", 8*Mi, 6),
143 MemCase("_high_memory", "; use a high texture memory usage limit", 256*Mi, 192)
146 static const struct Case
148 const char* const name;
149 const char* const desc;
150 const int numTextures; //!< If non-positive, taken from memoryLimitCases.
152 Case (const char* const name_, const char* const desc_, int numTextures_, const Probs& probs_ = Probs()) : name(name_), desc(desc_), numTextures(numTextures_), probs(probs_) {}
155 Case("always_reupload",
156 "Re-upload texture data at the beginning of each iteration",
158 Probs().pReuploadTexture(1.0f)),
160 Case("always_reupload_teximage",
161 "Re-upload texture data at the beginning of each iteration, using glTexImage*",
163 Probs().pReuploadTexture(1.0f).pReuploadWithTexImage(1.0f)),
165 Case("always_delete",
166 "Delete textures at the end of each iteration, and re-create at the beginning of the next",
168 Probs().pDeleteTexture(1.0f)),
171 "Don't reuse textures, and only delete them when given memory limit is reached",
173 Probs().pWastefulTextureMemoryUsage(1.0f))
176 TestCaseGroup* const textureGroup = new TestCaseGroup(m_context, "texture", "Texture stress tests");
177 addChild(textureGroup);
179 for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
181 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
183 const int numTextures = cases[caseNdx].numTextures > 0 ? cases[caseNdx].numTextures : memoryLimitCases[memoryLimitNdx].numTextures;
184 const std::vector<gls::ProgramContext> contexts (1, progLib.generateTextureContext(numTextures, 512, 512, 0.1f));
186 textureGroup->addChild(new gls::LongStressCase(m_context.getTestContext(), m_context.getRenderContext(),
187 (string() + cases[caseNdx].name + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
188 (string() + cases[caseNdx].desc + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
189 memoryLimitCases[memoryLimitNdx].limit, 1*Mi /* buf memory */,
190 1 /* draw calls per iteration */, 10000 /* tris per call */,
191 contexts, cases[caseNdx].probs,
192 GL_STATIC_DRAW, GL_STATIC_DRAW));
200 const std::vector<gls::ProgramContext> contexts(1, progLib.generateTextureContext(1, 128, 128, 0.5f));
202 static const struct Case
204 const char* const name;
205 const char* const desc;
206 const int drawCallsPerIteration;
207 const int numTrisPerDrawCall;
209 Case (const char* const name_, const char* const desc_, const int calls, const int tris, const Probs& probs_ = Probs())
210 : name(name_), desc(desc_), drawCallsPerIteration(calls), numTrisPerDrawCall(tris), probs(probs_) {}
213 Case("client_memory_data",
214 "Use client-memory for index and attribute data, instead of GL buffers",
216 Probs().pClientMemoryAttributeData(1.0f).pClientMemoryIndexData(1.0f)),
218 Case("vary_draw_function",
219 "Choose between glDrawElements and glDrawArrays each iteration, with uniform probability",
221 Probs().pUseDrawArrays(0.5f)),
223 Case("few_big_calls",
224 "Per iteration, do a few draw calls with a big number of triangles per call",
227 Case("many_small_calls",
228 "Per iteration, do many draw calls with a small number of triangles per call",
232 TestCaseGroup* const drawCallGroup = new TestCaseGroup(m_context, "draw_call", "Draw call stress tests");
233 addChild(drawCallGroup);
235 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
237 drawCallGroup->addChild(new gls::LongStressCase(m_context.getTestContext(), m_context.getRenderContext(),
238 cases[caseNdx].name, cases[caseNdx].desc,
239 1*Mi /* tex memory */, 2*Mi /* buf memory */,
240 cases[caseNdx].drawCallsPerIteration, cases[caseNdx].numTrisPerDrawCall,
241 contexts, cases[caseNdx].probs,
242 GL_STATIC_DRAW, GL_STATIC_DRAW));
249 std::vector<gls::ProgramContext> contexts;
250 contexts.push_back(progLib.generateFragmentPointLightContext(512, 512));
251 contexts.push_back(progLib.generateVertexUniformLoopLightContext(512, 512));
253 static const struct Case
255 const char* const name;
256 const char* const desc;
258 Case (const char* const name_, const char* const desc_, const Probs& probs_ = Probs()) : name(name_), desc(desc_), probs(probs_) {}
261 Case("several_programs",
262 "Use several different programs, choosing between them uniformly on each iteration"),
264 Case("several_programs_always_rebuild",
265 "Use several different programs, choosing between them uniformly on each iteration, and always rebuild the program",
266 Probs().pRebuildProgram(1.0f))
269 TestCaseGroup* const shaderGroup = new TestCaseGroup(m_context, "program", "Shader program stress tests");
270 addChild(shaderGroup);
272 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
274 shaderGroup->addChild(new gls::LongStressCase(m_context.getTestContext(), m_context.getRenderContext(),
275 cases[caseNdx].name, cases[caseNdx].desc,
276 3*Mi /* tex memory */, 1*Mi /* buf memory */,
277 1 /* draw calls per iteration */, 10000 /* tris per call */,
278 contexts, cases[caseNdx].probs,
279 GL_STATIC_DRAW, GL_STATIC_DRAW));
286 static const struct MemCase
288 const char* const nameSuffix;
289 const char* const descSuffix;
292 MemCase (const char* n, const char* d, int t, int b) : nameSuffix(n), descSuffix(d), texLimit(t), bufLimit(b) {}
293 } memoryLimitCases[] =
295 MemCase("_low_memory", "; use a low memory usage limit", 8*Mi, 8*Mi),
296 MemCase("_high_memory", "; use a high memory usage limit", 128*Mi, 128*Mi)
299 TestCaseGroup* const mixedGroup = new TestCaseGroup(m_context, "mixed", "Mixed stress tests");
300 addChild(mixedGroup);
302 for (int memoryLimitNdx = 0; memoryLimitNdx < DE_LENGTH_OF_ARRAY(memoryLimitCases); memoryLimitNdx++)
304 mixedGroup->addChild(new gls::LongStressCase(m_context.getTestContext(), m_context.getRenderContext(),
305 (string() + "buffer_texture_wasteful" + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
306 (string() + "Use both buffers and textures wastefully" + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
307 memoryLimitCases[memoryLimitNdx].texLimit, memoryLimitCases[memoryLimitNdx].bufLimit,
308 1 /* draw calls per iteration */, 10000 /* tris per call */,
309 std::vector<gls::ProgramContext>(1, progLib.generateBufferAndTextureContext(4, 512, 512)),
311 .pReuploadTexture (0.3f)
312 .pReuploadWithTexImage (0.5f)
313 .pReuploadBuffer (0.3f)
314 .pReuploadWithBufferData (0.5f)
315 .pDeleteTexture (0.2f)
316 .pDeleteBuffer (0.2f)
317 .pWastefulTextureMemoryUsage (0.5f)
318 .pWastefulBufferMemoryUsage (0.5f)
319 .pRandomBufferUploadTarget (1.0f)
320 .pRandomBufferUsage (1.0f),
321 GL_STATIC_DRAW, GL_STATIC_DRAW));
324 std::vector<gls::ProgramContext> contexts;
325 contexts.push_back(progLib.generateFragmentPointLightContext(512, 512));
326 contexts.push_back(progLib.generateVertexUniformLoopLightContext(512, 512));
327 mixedGroup->addChild(new gls::LongStressCase(m_context.getTestContext(), m_context.getRenderContext(),
328 (string() + "random" + memoryLimitCases[memoryLimitNdx].nameSuffix).c_str(),
329 (string() + "Highly random behavior" + memoryLimitCases[memoryLimitNdx].descSuffix).c_str(),
330 memoryLimitCases[memoryLimitNdx].texLimit, memoryLimitCases[memoryLimitNdx].bufLimit,
331 1 /* draw calls per iteration */, 10000 /* tris per call */,
334 .pRebuildProgram (0.3f)
335 .pReuploadTexture (0.3f)
336 .pReuploadWithTexImage (0.3f)
337 .pReuploadBuffer (0.3f)
338 .pReuploadWithBufferData (0.3f)
339 .pDeleteTexture (0.2f)
340 .pDeleteBuffer (0.2f)
341 .pWastefulTextureMemoryUsage (0.3f)
342 .pWastefulBufferMemoryUsage (0.3f)
343 .pClientMemoryAttributeData (0.2f)
344 .pClientMemoryIndexData (0.2f)
345 .pSeparateAttribBuffers (0.4f)
346 .pUseDrawArrays (0.4f)
347 .pRandomBufferUploadTarget (1.0f)
348 .pRandomBufferUsage (1.0f),
349 GL_STATIC_DRAW, GL_STATIC_DRAW));