1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 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 Memory object stress test
22 *//*--------------------------------------------------------------------*/
24 #include "glsMemoryStressCase.hpp"
25 #include "gluShaderProgram.hpp"
26 #include "tcuTestLog.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "deRandom.hpp"
45 static const char* glErrorToString (deUint32 error)
49 case GL_OUT_OF_MEMORY:
50 return "GL_OUT_OF_MEMORY";
54 return "GL_INVALID_ENUM";
57 case GL_INVALID_FRAMEBUFFER_OPERATION:
58 return "GL_INVALID_FRAMEBUFFER_OPERATION";
61 case GL_INVALID_OPERATION:
62 return "GL_INVALID_OPERATION";
65 case GL_INVALID_VALUE:
66 return "GL_INVALID_VALUE";
74 // \todo [mika] Handle uknown errors?
81 static const float s_quadCoords[] =
89 static const GLubyte s_quadIndices[] =
98 TextureRenderer (tcu::TestLog& log, glu::RenderContext& renderContext);
99 ~TextureRenderer (void);
100 void render (deUint32 texture);
103 glu::ShaderProgram* m_program;
104 glu::RenderContext& m_renderCtx;
106 deUint32 m_coordBuffer;
107 deUint32 m_indexBuffer;
110 static const char* s_vertexShaderGLES2;
111 static const char* s_fragmentShaderGLES2;
113 static const char* s_vertexShaderGLES3;
114 static const char* s_fragmentShaderGLES3;
116 static const char* s_vertexShaderGL3;
117 static const char* s_fragmentShaderGL3;
120 const char* TextureRenderer::s_vertexShaderGLES2 =
121 "attribute mediump vec2 a_coord;\n"
122 "varying mediump vec2 v_texCoord;\n"
125 "\tv_texCoord = 0.5 * (a_coord + vec2(1.0));\n"
126 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
129 const char* TextureRenderer::s_fragmentShaderGLES2 =
130 "varying mediump vec2 v_texCoord;\n"
131 "uniform sampler2D u_texture;\n"
134 "\tgl_FragColor = texture2D(u_texture, v_texCoord);\n"
137 const char* TextureRenderer::s_vertexShaderGLES3 =
139 "in mediump vec2 a_coord;\n"
140 "out mediump vec2 v_texCoord;\n"
143 "\tv_texCoord = 0.5 * (a_coord + vec2(1.0));\n"
144 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
147 const char* TextureRenderer::s_fragmentShaderGLES3 =
149 "in mediump vec2 v_texCoord;\n"
150 "uniform sampler2D u_texture;\n"
151 "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
154 "\tdEQP_FragColor = texture(u_texture, v_texCoord);\n"
157 const char* TextureRenderer::s_vertexShaderGL3 =
159 "in mediump vec2 a_coord;\n"
160 "out mediump vec2 v_texCoord;\n"
163 "\tv_texCoord = 0.5 * (a_coord + vec2(1.0));\n"
164 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
167 const char* TextureRenderer::s_fragmentShaderGL3 =
169 "in mediump vec2 v_texCoord;\n"
170 "uniform sampler2D u_texture;\n"
171 "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
174 "\tdEQP_FragColor = texture(u_texture, v_texCoord);\n"
177 TextureRenderer::TextureRenderer (tcu::TestLog& log, glu::RenderContext& renderContext)
179 , m_renderCtx (renderContext)
184 const glu::ContextType ctxType = renderContext.getType();
186 if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_300_ES))
187 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGLES3, s_fragmentShaderGLES3));
188 else if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_100_ES))
189 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGLES2, s_fragmentShaderGLES2));
190 else if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_330))
191 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGL3, s_fragmentShaderGL3));
195 if (ctxType.getProfile() == glu::PROFILE_CORE)
196 GLU_CHECK_CALL(glGenVertexArrays(1, &m_vao));
198 GLU_CHECK_CALL(glGenBuffers(1, &m_coordBuffer));
199 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_coordBuffer));
200 GLU_CHECK_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(s_quadCoords), s_quadCoords, GL_STATIC_DRAW));
202 GLU_CHECK_CALL(glGenBuffers(1, &m_indexBuffer));
203 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer));
204 GLU_CHECK_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(s_quadIndices), s_quadIndices, GL_STATIC_DRAW));
206 if (!m_program->isOk())
209 TCU_CHECK_MSG(m_program->isOk(), "Shader compilation failed");
213 TextureRenderer::~TextureRenderer (void)
216 glDeleteBuffers(1, &m_coordBuffer);
217 glDeleteBuffers(1, &m_indexBuffer);
220 void TextureRenderer::render (deUint32 texture)
222 deUint32 coordLoc = -1;
223 deUint32 texLoc = -1;
225 GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
227 coordLoc = glGetAttribLocation(m_program->getProgram(), "a_coord");
229 TCU_CHECK(coordLoc != (deUint32)-1);
232 GLU_CHECK_CALL(glBindVertexArray(m_vao));
234 GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
236 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_coordBuffer));
237 GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL));
239 GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0));
240 GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, texture));
242 texLoc = glGetUniformLocation(m_program->getProgram(), "u_texture");
244 TCU_CHECK(texLoc != (deUint32)-1);
246 GLU_CHECK_CALL(glUniform1i(texLoc, 0));
248 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer));
249 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, NULL));
251 GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
254 GLU_CHECK_CALL(glBindVertexArray(0));
260 BufferRenderer (tcu::TestLog& log, glu::RenderContext& renderContext);
261 ~BufferRenderer (void);
262 void render (deUint32 buffer, int size);
265 glu::ShaderProgram* m_program;
266 glu::RenderContext& m_renderCtx;
268 deUint32 m_coordBuffer;
269 deUint32 m_indexBuffer;
272 static const char* s_vertexShaderGLES2;
273 static const char* s_fragmentShaderGLES2;
275 static const char* s_vertexShaderGLES3;
276 static const char* s_fragmentShaderGLES3;
278 static const char* s_vertexShaderGL3;
279 static const char* s_fragmentShaderGL3;
282 const char* BufferRenderer::s_vertexShaderGLES2 =
283 "attribute mediump vec2 a_coord;\n"
284 "attribute mediump vec4 a_buffer;\n"
285 "varying mediump vec4 v_buffer;\n"
288 "\tv_buffer = a_buffer;\n"
289 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
292 const char* BufferRenderer::s_fragmentShaderGLES2 =
293 "varying mediump vec4 v_buffer;\n"
296 "\tgl_FragColor = v_buffer;\n"
299 const char* BufferRenderer::s_vertexShaderGLES3 =
301 "in mediump vec2 a_coord;\n"
302 "in mediump vec4 a_buffer;\n"
303 "out mediump vec4 v_buffer;\n"
306 "\tv_buffer = a_buffer;\n"
307 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
310 const char* BufferRenderer::s_fragmentShaderGLES3 =
312 "in mediump vec4 v_buffer;\n"
313 "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
316 "\tdEQP_FragColor = v_buffer;\n"
319 const char* BufferRenderer::s_vertexShaderGL3 =
321 "in mediump vec2 a_coord;\n"
322 "in mediump vec4 a_buffer;\n"
323 "out mediump vec4 v_buffer;\n"
326 "\tv_buffer = a_buffer;\n"
327 "\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
330 const char* BufferRenderer::s_fragmentShaderGL3 =
332 "in mediump vec4 v_buffer;\n"
333 "layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
336 "\tdEQP_FragColor = v_buffer;\n"
339 BufferRenderer::BufferRenderer (tcu::TestLog& log, glu::RenderContext& renderContext)
341 , m_renderCtx (renderContext)
346 const glu::ContextType ctxType = renderContext.getType();
348 if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_300_ES))
349 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGLES3, s_fragmentShaderGLES3));
350 else if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_100_ES))
351 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGLES2, s_fragmentShaderGLES2));
352 else if (glu::isGLSLVersionSupported(ctxType, glu::GLSL_VERSION_330))
353 m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(s_vertexShaderGL3, s_fragmentShaderGL3));
357 if (ctxType.getProfile() == glu::PROFILE_CORE)
358 GLU_CHECK_CALL(glGenVertexArrays(1, &m_vao));
360 GLU_CHECK_CALL(glGenBuffers(1, &m_coordBuffer));
361 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_coordBuffer));
362 GLU_CHECK_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(s_quadCoords), s_quadCoords, GL_STATIC_DRAW));
364 GLU_CHECK_CALL(glGenBuffers(1, &m_indexBuffer));
365 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer));
366 GLU_CHECK_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(s_quadIndices), s_quadIndices, GL_STATIC_DRAW));
368 if (!m_program->isOk())
371 TCU_CHECK_MSG(m_program->isOk(), "Shader compilation failed");
375 BufferRenderer::~BufferRenderer (void)
378 glDeleteBuffers(1, &m_coordBuffer);
379 glDeleteBuffers(1, &m_indexBuffer);
382 void BufferRenderer::render (deUint32 buffer, int size)
385 DE_ASSERT((size_t)size >= sizeof(GLubyte) * 4 * 6);
386 GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
388 deUint32 bufferLoc = glGetAttribLocation(m_program->getProgram(), "a_buffer");
389 TCU_CHECK(bufferLoc != (deUint32)-1);
391 deUint32 coordLoc = glGetAttribLocation(m_program->getProgram(), "a_coord");
392 TCU_CHECK(coordLoc != (deUint32)-1);
395 GLU_CHECK_CALL(glBindVertexArray(m_vao));
397 GLU_CHECK_CALL(glEnableVertexAttribArray(bufferLoc));
398 GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
400 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_coordBuffer));
401 GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL));
403 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffer));
404 GLU_CHECK_CALL(glVertexAttribPointer(bufferLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0));
405 GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
407 GLU_CHECK_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer));
408 GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, NULL));
410 GLU_CHECK_CALL(glDisableVertexAttribArray(bufferLoc));
411 GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
414 GLU_CHECK_CALL(glBindVertexArray(0));
417 class MemObjectAllocator
422 RESULT_GOT_BAD_ALLOC = 0,
423 RESULT_GEN_TEXTURES_FAILED,
424 RESULT_GEN_BUFFERS_FAILED,
425 RESULT_BUFFER_DATA_FAILED,
426 RESULT_BUFFER_SUB_DATA_FAILED,
427 RESULT_TEXTURE_IMAGE_FAILED,
428 RESULT_TEXTURE_SUB_IMAGE_FAILED,
429 RESULT_BIND_TEXTURE_FAILED,
430 RESULT_BIND_BUFFER_FAILED,
431 RESULT_DELETE_TEXTURES_FAILED,
432 RESULT_DELETE_BUFFERS_FAILED,
433 RESULT_RENDER_FAILED,
438 MemObjectAllocator (tcu::TestLog& log, glu::RenderContext& renderContext, MemObjectType objectTypes, const MemObjectConfig& config, int seed);
439 ~MemObjectAllocator (void);
440 bool allocUntilFailure (void);
441 void clearObjects (void);
442 Result getResult (void) const { return m_result; }
443 deUint32 getGLError (void) const { return m_glError; }
444 int getObjectCount (void) const { return m_objectCount; }
445 deUint32 getBytes (void) const { return m_bytesRequired; }
447 static const char* resultToString (Result result);
451 void allocateTexture (de::Random& rnd);
452 void allocateBuffer (de::Random& rnd);
454 vector<deUint32> m_buffers;
455 vector<deUint32> m_textures;
458 deUint32 m_bytesRequired;
459 MemObjectType m_objectTypes;
461 MemObjectConfig m_config;
463 vector<deUint8> m_dummyData;
464 BufferRenderer m_bufferRenderer;
465 TextureRenderer m_textureRenderer;
468 MemObjectAllocator::MemObjectAllocator (tcu::TestLog& log, glu::RenderContext& renderContext, MemObjectType objectTypes, const MemObjectConfig& config, int seed)
471 , m_bytesRequired (0)
472 , m_objectTypes (objectTypes)
473 , m_result (RESULT_LAST)
476 , m_bufferRenderer (log, renderContext)
477 , m_textureRenderer (log, renderContext)
479 DE_UNREF(renderContext);
481 if (m_config.useDummyData)
483 int dummySize = deMax32(m_config.maxBufferSize, m_config.maxTextureSize*m_config.maxTextureSize*4);
484 m_dummyData = vector<deUint8>(dummySize);
486 else if (m_config.write)
487 m_dummyData = vector<deUint8>(128);
490 MemObjectAllocator::~MemObjectAllocator (void)
494 bool MemObjectAllocator::allocUntilFailure (void)
496 de::Random rnd(m_seed);
497 GLU_CHECK_MSG("Error in init");
500 const deUint64 timeoutUs = 10000000; // 10s
501 deUint64 beginTimeUs = deGetMicroseconds();
502 deUint64 currentTimeUs;
506 GLU_CHECK_MSG("Unkown Error");
507 switch (m_objectTypes)
509 case MEMOBJECTTYPE_TEXTURE:
510 allocateTexture(rnd);
513 case MEMOBJECTTYPE_BUFFER:
522 allocateTexture(rnd);
527 if (m_result != RESULT_LAST)
533 currentTimeUs = deGetMicroseconds();
534 } while (currentTimeUs - beginTimeUs < timeoutUs);
537 if (currentTimeUs - beginTimeUs >= timeoutUs)
542 catch (const std::bad_alloc&)
544 m_result = RESULT_GOT_BAD_ALLOC;
549 void MemObjectAllocator::clearObjects (void)
553 if (!m_textures.empty())
555 glDeleteTextures((GLsizei)m_textures.size(), &(m_textures[0]));
556 error = glGetError();
559 m_result = RESULT_DELETE_TEXTURES_FAILED;
566 if (!m_buffers.empty())
568 glDeleteBuffers((GLsizei)m_buffers.size(), &(m_buffers[0]));
569 error = glGetError();
572 m_result = RESULT_DELETE_BUFFERS_FAILED;
580 void MemObjectAllocator::allocateTexture (de::Random& rnd)
582 const int vectorBlockSize = 128;
585 int width = rnd.getInt(m_config.minTextureSize, m_config.maxTextureSize);
586 int height = rnd.getInt(m_config.minTextureSize, m_config.maxTextureSize);
588 glGenTextures(1, &tex);
589 error = glGetError();
592 m_result = RESULT_GEN_TEXTURES_FAILED;
597 if (m_textures.size() % vectorBlockSize == 0)
598 m_textures.reserve(m_textures.size() + vectorBlockSize);
600 m_textures.push_back(tex);
602 glBindTexture(GL_TEXTURE_2D, tex);
603 error = glGetError();
606 m_result = RESULT_BIND_TEXTURE_FAILED;
611 if (m_config.useDummyData)
613 DE_ASSERT((int)m_dummyData.size() >= width*height*4);
614 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(m_dummyData[0]));
617 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
619 error = glGetError();
622 m_result = RESULT_TEXTURE_IMAGE_FAILED;
628 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &(m_dummyData[0]));
630 error = glGetError();
633 m_result = RESULT_TEXTURE_SUB_IMAGE_FAILED;
642 m_textureRenderer.render(tex);
644 catch (const glu::Error& err)
646 m_result = RESULT_RENDER_FAILED;
647 m_glError = err.getError();
650 catch (const glu::OutOfMemoryError&)
652 m_result = RESULT_RENDER_FAILED;
653 m_glError = GL_OUT_OF_MEMORY;
658 glBindTexture(GL_TEXTURE_2D, 0);
659 error = glGetError();
662 m_result = RESULT_BIND_TEXTURE_FAILED;
668 m_bytesRequired += width*height*4;
671 void MemObjectAllocator::allocateBuffer (de::Random& rnd)
673 const int vectorBlockSize = 128;
676 int size = rnd.getInt(m_config.minBufferSize, m_config.maxBufferSize);
678 glGenBuffers(1, &buffer);
679 error = glGetError();
682 m_result = RESULT_GEN_BUFFERS_FAILED;
687 glBindBuffer(GL_ARRAY_BUFFER, buffer);
688 error = glGetError();
691 m_result = RESULT_BIND_BUFFER_FAILED;
696 if (m_buffers.size() % vectorBlockSize == 0)
697 m_buffers.reserve(m_buffers.size() + vectorBlockSize);
699 m_buffers.push_back(buffer);
701 if (m_config.useDummyData)
703 DE_ASSERT((int)m_dummyData.size() >= size);
704 glBufferData(GL_ARRAY_BUFFER, size, &(m_dummyData[0]), GL_DYNAMIC_DRAW);
707 glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
709 error = glGetError();
712 m_result = RESULT_BUFFER_DATA_FAILED;
718 glBufferSubData(GL_ARRAY_BUFFER, 0, 1, &(m_dummyData[0]));
720 error = glGetError();
723 m_result = RESULT_BUFFER_SUB_DATA_FAILED;
732 m_bufferRenderer.render(buffer, size);
734 catch (const glu::Error& err)
736 m_result = RESULT_RENDER_FAILED;
737 m_glError = err.getError();
740 catch (const glu::OutOfMemoryError&)
742 m_result = RESULT_RENDER_FAILED;
743 m_glError = GL_OUT_OF_MEMORY;
748 glBindBuffer(GL_ARRAY_BUFFER, 0);
749 error = glGetError();
752 m_result = RESULT_BIND_BUFFER_FAILED;
758 m_bytesRequired += size;
761 const char* MemObjectAllocator::resultToString (Result result)
765 case RESULT_GOT_BAD_ALLOC:
766 return "Caught std::bad_alloc";
769 case RESULT_GEN_TEXTURES_FAILED:
770 return "glGenTextures failed";
773 case RESULT_GEN_BUFFERS_FAILED:
774 return "glGenBuffers failed";
777 case RESULT_BUFFER_DATA_FAILED:
778 return "glBufferData failed";
781 case RESULT_BUFFER_SUB_DATA_FAILED:
782 return "glBufferSubData failed";
785 case RESULT_TEXTURE_IMAGE_FAILED:
786 return "glTexImage2D failed";
789 case RESULT_TEXTURE_SUB_IMAGE_FAILED:
790 return "glTexSubImage2D failed";
793 case RESULT_BIND_TEXTURE_FAILED:
794 return "glBindTexture failed";
797 case RESULT_BIND_BUFFER_FAILED:
798 return "glBindBuffer failed";
801 case RESULT_DELETE_TEXTURES_FAILED:
802 return "glDeleteTextures failed";
805 case RESULT_DELETE_BUFFERS_FAILED:
806 return "glDeleteBuffers failed";
809 case RESULT_RENDER_FAILED:
810 return "Rendering result failed";
819 MemoryStressCase::MemoryStressCase (tcu::TestContext& ctx, glu::RenderContext& renderContext, deUint32 objectTypes, int minTextureSize, int maxTextureSize, int minBufferSize, int maxBufferSize, bool write, bool use, bool useDummyData, bool clearAfterOOM, const char* name, const char* desc)
820 : tcu::TestCase (ctx, name, desc)
822 , m_iterationCount (5)
823 , m_objectTypes ((MemObjectType)objectTypes)
824 , m_zeroAlloc (false)
825 , m_clearAfterOOM (clearAfterOOM)
826 , m_renderCtx (renderContext)
828 m_allocated.reserve(m_iterationCount);
829 m_config.maxTextureSize = maxTextureSize;
830 m_config.minTextureSize = minTextureSize;
831 m_config.maxBufferSize = maxBufferSize;
832 m_config.minBufferSize = minBufferSize;
833 m_config.useDummyData = useDummyData;
834 m_config.write = write;
838 MemoryStressCase::~MemoryStressCase (void)
842 void MemoryStressCase::init (void)
844 if (!m_testCtx.getCommandLine().isOutOfMemoryTestEnabled())
846 m_testCtx.getLog() << TestLog::Message << "Tests that exhaust memory are disabled, use --deqp-test-oom=enable command line option to enable." << TestLog::EndMessage;
847 throw tcu::NotSupportedError("OOM tests disabled");
851 void MemoryStressCase::deinit (void)
853 TCU_CHECK(!m_zeroAlloc);
856 tcu::TestCase::IterateResult MemoryStressCase::iterate (void)
859 tcu::TestLog& log = m_testCtx.getLog();
861 MemObjectAllocator allocator(log, m_renderCtx, m_objectTypes, m_config, deStringHash(getName()));
863 if (!allocator.allocUntilFailure())
865 // Allocation timed out
866 allocator.clearObjects();
868 log << TestLog::Message << "Timeout. Couldn't exhaust memory in timelimit. Allocated " << allocator.getObjectCount() << " objects." << TestLog::EndMessage;
870 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
874 // Try to cancel rendering operations
876 GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
878 allocator.clearObjects();
880 m_allocated.push_back(allocator.getObjectCount());
882 if (m_iteration != 0 && allocator.getObjectCount() == 0)
885 log << TestLog::Message << "Got error when allocation object count: " << allocator.getObjectCount() << " bytes: " << allocator.getBytes() << TestLog::EndMessage;
887 if ((allocator.getGLError() == 0) && (allocator.getResult() == MemObjectAllocator::RESULT_GOT_BAD_ALLOC))
889 log << TestLog::Message << "std::bad_alloc" << TestLog::EndMessage;
891 m_testCtx.setTestResult(QP_TEST_RESULT_RESOURCE_ERROR, "Memory allocation failed");
893 else if (allocator.getGLError() != GL_OUT_OF_MEMORY)
895 log << TestLog::Message << "Invalid Error " << MemObjectAllocator::resultToString(allocator.getResult())
896 << " GLError: " << glErrorToString(allocator.getGLError()) <<
900 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
903 if ((m_iteration+1) == m_iterationCount)
905 int min = m_allocated[0];
906 int max = m_allocated[0];
908 float threshold = 50.0f;
910 for (int allocNdx = 0; allocNdx < (int)m_allocated.size(); allocNdx++)
912 min = deMin32(m_allocated[allocNdx], min);
913 max = deMax32(m_allocated[allocNdx], max);
916 if (min == 0 && max != 0)
918 log << TestLog::Message << "Allocation count zero" << TestLog::EndMessage;
919 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
923 const float change = (min - max) / ((float)(max));
924 if (change > threshold)
926 log << TestLog::Message << "Allocated objects max: " << max << ", min: " << min << ", difference: " << change << "% threshold: " << threshold << "%" << TestLog::EndMessage;
927 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Allocation count variation");
930 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
935 GLU_CHECK_CALL(glFinish());